From 25704deafb3bacf0dd30e8aa186d9f160618b907 Mon Sep 17 00:00:00 2001 From: Hallvard Traetteberg <hal@ntnu.no> Date: Fri, 9 Mar 2018 11:15:31 +0100 Subject: [PATCH] Extend and refactor domain model. --- .../java/tdt4140/gr1800/app/core/App.java | 2 +- .../tdt4140/gr1800/app/core/GeoLocation.java | 22 --- .../tdt4140/gr1800/app/core/GeoLocations.java | 29 +++- .../gr1800/app/core/GeoLocationsOwner.java | 100 +++++++++++++ ...ava => GeoLocationsStreamPersistence.java} | 2 +- .../java/tdt4140/gr1800/app/core/Tagged.java | 3 + .../java/tdt4140/gr1800/app/core/Tags.java | 54 ++++++- .../gr1800/app/core/TimedTaggedImpl.java | 36 +++++ .../app/geojson/GeoJsonDocumentConverter.java | 67 +++++++++ .../app/geojson/GeoJsonDocumentLoader.java | 17 +++ .../app/json/GeoLocationsJsonPersistence.java | 4 +- .../java/tdt4140/gr1800/app/core/AppTest.java | 2 +- .../app/core/GeoLocationsOwnerTest.java | 141 ++++++++++++++++++ ...=> GeoLocationsStreamPersistenceTest.java} | 6 +- .../gr1800/app/core/GeoLocationsTest.java | 2 +- .../gr1800/app/core/TimedTaggedTest.java | 37 +++++ .../java/tdt4140/gr1800/app/ui/FxAppTest.java | 2 - .../tdt4140/gr1800/web/server/GeoServlet.java | 57 ++++++- .../web/server/GeoLocationsServerIT.java | 4 +- 19 files changed, 544 insertions(+), 43 deletions(-) create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsOwner.java rename tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/{GeoLocationsPersistence.java => GeoLocationsStreamPersistence.java} (86%) create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentConverter.java create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentLoader.java create mode 100644 tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsOwnerTest.java rename tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/{GeoLocationsPersistenceTest.java => GeoLocationsStreamPersistenceTest.java} (92%) diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java index 8325b47..ff351af 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java @@ -21,7 +21,7 @@ import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; public class App { - private GeoLocationsPersistence geoLocationsPersistence = new GeoLocationsJsonPersistence(); + private GeoLocationsStreamPersistence geoLocationsPersistence = new GeoLocationsJsonPersistence(); private Collection<GeoLocations> geoLocations = null; diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocation.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocation.java index 6fb4f23..5c6d552 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocation.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocation.java @@ -35,26 +35,4 @@ public class GeoLocation extends TimedTaggedImpl implements GeoLocated, Timed, T public void setDescription(String description) { this.description = description; } - - // - - private Tags tags = null; - - @Override - public boolean hasTags(String... tags) { - return this.tags != null && this.tags.hasTags(tags); - } - - public void addTags(String... tags) { - if (this.tags == null) { - this.tags = new Tags(); - } - this.tags.addTags(tags); - } - - public void removeTags(String... tags) { - if (this.tags != null) { - this.tags.removeTags(tags); - } - } } diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java index 8eeaf5c..2d373b2 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java @@ -9,6 +9,16 @@ import java.util.stream.Collectors; public class GeoLocations extends TimedTaggedImpl implements Iterable<GeoLocated>, Tagged, Timed { + private final GeoLocationsOwner owner; + + public GeoLocations(GeoLocationsOwner owner) { + this.owner = owner; + } + + public GeoLocationsOwner getOwner() { + return owner; + } + private String name; public String getName() { @@ -19,12 +29,23 @@ public class GeoLocations extends TimedTaggedImpl implements Iterable<GeoLocated this.name = name; } + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + private Collection<GeoLocated> locations = new ArrayList<GeoLocated>(); private boolean path = false; - public GeoLocations(LatLong...latLongs) { - for (int i = 0; i < latLongs.length; i++) { - addLocation(latLongs[i]); + public GeoLocations(GeoLocated...geoLocs) { + this((GeoLocationsOwner) null); + for (int i = 0; i < geoLocs.length; i++) { + addLocation(geoLocs[i]); } } @@ -60,7 +81,7 @@ public class GeoLocations extends TimedTaggedImpl implements Iterable<GeoLocated // - public void addLocation(LatLong geoLoc) { + public void addLocation(GeoLocated geoLoc) { locations.add(geoLoc); } diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsOwner.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsOwner.java new file mode 100644 index 0000000..55c54ef --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsOwner.java @@ -0,0 +1,100 @@ +package tdt4140.gr1800.app.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class GeoLocationsOwner { + + private Collection<GeoLocations> geoLocations = null; + + public Iterable<String> getGeoLocationsNames() { + Collection<String> names = new ArrayList<String>(geoLocations != null ? geoLocations.size() : 0); + if (geoLocations != null) { + for (GeoLocations geoLocations : geoLocations) { + names.add(geoLocations.getName()); + } + } + return names; + } + + public boolean hasGeoLocations(String... names) { + if (geoLocations != null) { + outer: for (String name : names) { + for (GeoLocations geoLocations : geoLocations) { + if (name.equals(geoLocations.getName())) { + continue outer; + } + } + return false; + } + return true; + } + return names.length == 0; + } + + public GeoLocations getGeoLocations(String name) { + if (geoLocations != null) { + for (GeoLocations geoLocations : geoLocations) { + if (name.equals(geoLocations.getName())) { + return geoLocations; + } + } + } + return null; + } + + public Collection<GeoLocations> getGeoLocations(String... names) { + Collection<GeoLocations> result = new ArrayList<GeoLocations>(); + if (geoLocations != null) { + if (names != null) { + for (GeoLocations geoLocations : geoLocations) { + for (String name : names) { + if (name.equals(geoLocations.getName())) { + result.add(geoLocations); + } + } + } + } else { + result.addAll(geoLocations); + } + } + return result; + } + + // + + public void removeGeolocations(String... names) { + if (geoLocations != null) { + Iterator<GeoLocations> it = geoLocations.iterator(); + while (it.hasNext()) { + GeoLocations next = it.next(); + if (names != null) { + for (String name : names) { + if (name.equals(next.getName())) { + it.remove(); + break; + } + } + } else { + it.remove(); + } + } + } + } + + public void addGeolocations(GeoLocations geoLocations) { + if (this.geoLocations == null) { + this.geoLocations = new ArrayList<>(); + } + if (! this.geoLocations.contains(geoLocations)) { + this.geoLocations.add(geoLocations); + } + } + + public void removeGeolocations(GeoLocations geoLocations) { + if (this.geoLocations != null) { + this.geoLocations.remove(geoLocations); + } + } +} 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/GeoLocationsStreamPersistence.java similarity index 86% rename from tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsPersistence.java rename to tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsStreamPersistence.java index 27798ef..98a7099 100644 --- 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/GeoLocationsStreamPersistence.java @@ -4,7 +4,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Collection; -public interface GeoLocationsPersistence { +public interface GeoLocationsStreamPersistence { 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/core/Tagged.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tagged.java index f6bacd1..ddd1ae7 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tagged.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tagged.java @@ -2,6 +2,9 @@ package tdt4140.gr1800.app.core; public interface Tagged { public boolean hasTags(String... tags); + public String[] getTags(); + public String getTags(String prefix, String separator, String suffix); + public void setTags(String... tags); public void addTags(String... tags); public void removeTags(String... tags); } diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tags.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tags.java index 8fdc743..58c01a3 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tags.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/Tags.java @@ -9,18 +9,66 @@ public class Tags implements Tagged { private Collection<String> tags = null; public Tags(String... tags) { - addTags(tags); + setTags(tags); } - + + public Tags(Tagged tags) { + setTags(tags.getTags()); + } + + public static Tags valueOf(String tags) { + return valueOf(tags, ","); + } + + public static Tags valueOf(String tags, String separator) { + return new Tags(tags.split(separator)); + } + public int getTagCount() { return (tags == null ? 0 : tags.size()); } @Override public boolean hasTags(String... tags) { - return this.tags != null && this.tags.containsAll(Arrays.asList(tags)); + return (tags.length == 0 || (this.tags != null && this.tags.containsAll(Arrays.asList(tags)))); + } + + final static String[] EMPTY_STRINGS = {}; + + @Override + public String[] getTags() { + return (tags != null ? tags.toArray(new String[tags.size()]) : EMPTY_STRINGS); } + @Override + public String getTags(String prefix, String separator, String suffix) { + StringBuilder buffer = new StringBuilder(); + append(buffer, prefix); + int tagNum = 0; + for (String tag : tags) { + if (tagNum > 0 && separator != null) { + buffer.append(separator); + } + buffer.append(tag); + tagNum++; + } + append(buffer, suffix); + return buffer.toString(); + } + + static StringBuilder append(StringBuilder buffer, String s) { + if (s != null) { + buffer.append(s); + } + return buffer; + } + + @Override + public void setTags(String... tags) { + this.tags = new ArrayList<>(); + addTags(tags); + } + public void addTags(String... tags) { if (this.tags == null && tags != null && tags.length > 0) { this.tags = new ArrayList<>(); diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/TimedTaggedImpl.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/TimedTaggedImpl.java index 09a6511..c8ccbdf 100644 --- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/TimedTaggedImpl.java +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/TimedTaggedImpl.java @@ -4,11 +4,47 @@ public class TimedTaggedImpl extends TimedImpl implements Tagged { private Tags tags = null; + public TimedTaggedImpl() { + } + + public TimedTaggedImpl(Tagged tags) { + setTags(tags.getTags()); + } + + private static TimedTaggedImpl valueOf(Tags tags) { + TimedTaggedImpl timedTags = new TimedTaggedImpl(); + timedTags.tags = tags; + return timedTags; + } + + public static TimedTaggedImpl valueOf(String tags) { + return valueOf(Tags.valueOf(tags)); + } + + public static TimedTaggedImpl valueOf(String tags, String separator) { + return valueOf(Tags.valueOf(tags, separator)); + } + @Override public boolean hasTags(String... tags) { return this.tags != null && this.tags.hasTags(tags); } + + @Override + public String[] getTags() { + return (tags != null ? tags.getTags() : Tags.EMPTY_STRINGS); + } + @Override + public String getTags(String prefix, String separator, String suffix) { + return (tags != null ? tags.getTags(prefix, separator, suffix) : Tags.append(Tags.append(new StringBuilder(), prefix), suffix).toString()); + } + + @Override + public void setTags(String... tags) { + this.tags = (tags != null && tags.length > 0 ? new Tags(tags) : null); + } + public void addTags(String... tags) { if (this.tags == null) { this.tags = new Tags(); diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentConverter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentConverter.java new file mode 100644 index 0000000..8794aab --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentConverter.java @@ -0,0 +1,67 @@ +package tdt4140.gr1800.app.geojson; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.stream.Collectors; + +import org.geojson.GeoJsonObject; +import org.geojson.LngLatAlt; + +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.LatLong; +import tdt4140.gr1800.app.doc.IDocumentLoader; + +public class GeoJsonDocumentConverter implements IDocumentLoader<Collection<GeoLocations>> { + + private GeoJsonDocumentLoader geoJsonLoader = new GeoJsonDocumentLoader(); + + @Override + public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception { + GeoJsonObject geoJson = geoJsonLoader.loadDocument(inputStream); + return convert(geoJson); + } + + private String trackNameFormat = "%s"; + private String trackCountFormat = "Track %s"; + private String trackSegmentFormat = "%s.%s"; + + public void setTrackNameFormat(String trackNameFormat) { + this.trackNameFormat = trackNameFormat; + } + + public void setTrackCountFormat(String trackCountFormat) { + this.trackCountFormat = trackCountFormat; + } + + public void setTrackSegmentFormat(String trackSegmentFormat) { + this.trackSegmentFormat = trackSegmentFormat; + } + + private String routeNameFormat = "%s"; + private String routeCountFormat = "Route %s"; + + public void setRouteNameFormat(String routeNameFormat) { + this.routeNameFormat = routeNameFormat; + } + + public void setRouteCountFormat(String routeCountFormat) { + this.routeCountFormat = routeCountFormat; + } + + public Collection<GeoLocations> convert(GeoJsonObject geoJson) throws Exception { + Collection<GeoLocations> geoLocations = new ArrayList<GeoLocations>(); + return geoLocations; + } + + private LatLong[] convert(Collection<LngLatAlt> points) { + Collection<LatLong> latLongs = points.stream() + .map(point -> convert(point)) + .collect(Collectors.toList()); + return latLongs.toArray(new LatLong[latLongs.size()]); + } + + private LatLong convert(LngLatAlt point) { + return new LatLong(point.getLatitude(), point.getLongitude()); + } +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentLoader.java new file mode 100644 index 0000000..612f4b4 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/geojson/GeoJsonDocumentLoader.java @@ -0,0 +1,17 @@ +package tdt4140.gr1800.app.geojson; + +import java.io.InputStream; + +import org.geojson.GeoJsonObject; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import tdt4140.gr1800.app.doc.IDocumentLoader; + +public class GeoJsonDocumentLoader implements IDocumentLoader<GeoJsonObject> { + + @Override + public GeoJsonObject loadDocument(InputStream inputStream) throws Exception { + return new ObjectMapper().readValue(inputStream, GeoJsonObject.class); + } +} 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 index 48804fb..66a078e 100644 --- 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 @@ -9,9 +9,9 @@ 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; +import tdt4140.gr1800.app.core.GeoLocationsStreamPersistence; -public class GeoLocationsJsonPersistence implements GeoLocationsPersistence { +public class GeoLocationsJsonPersistence implements GeoLocationsStreamPersistence { private final ObjectMapper objectMapper; diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java index 60baab3..fc5e13c 100644 --- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/AppTest.java @@ -35,7 +35,7 @@ public class AppTest { Assert.fail("Couldn't open " + file); } Assert.assertEquals(file, documentStorage.getDocumentLocation()); - GeoLocationsPersistenceTest.testGeoLocationsDotJson(app.getGeoLocations((String[]) null)); + GeoLocationsStreamPersistenceTest.testGeoLocationsDotJson(app.getGeoLocations((String[]) null)); } @Test diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsOwnerTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsOwnerTest.java new file mode 100644 index 0000000..15bc437 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsOwnerTest.java @@ -0,0 +1,141 @@ +package tdt4140.gr1800.app.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class GeoLocationsOwnerTest { + + private GeoLocationsOwner owner; + + @Before + public void setUp() { + this.owner = new GeoLocationsOwner(); + } + + private static <T> void check(Iterable<T> iterable, T... ts) { + check(iterable, false, ts); + } + + private static <T> void check(Iterable<T> iterable, boolean anyOrder, T... ts) { + Collection<T> all = (anyOrder ? Arrays.asList(ts) : null); + int num = 0; + for (Iterator<T> it = iterable.iterator(); it.hasNext(); num++) { + Assert.assertTrue(num < ts.length); + T next = it.next(); + if (anyOrder) { + assertTrue(all.contains(next)); + } else { + Assert.assertEquals(ts[num], next); + } + } + Assert.assertTrue(num == ts.length); + } + + private static int size(Iterable<?> iterable) { + int size = 0; + for (Iterator<?> it = iterable.iterator(); it.hasNext(); it.next()) { + size++; + } + return size; + } + + @Test + public void testGetGeoLocationNames() { + Assert.assertEquals(0, size(owner.getGeoLocationsNames())); + owner.addGeolocations(new GeoLocations("test1")); + check(owner.getGeoLocationsNames(), "test1"); + owner.addGeolocations(new GeoLocations("test2")); + check(owner.getGeoLocationsNames(), "test1", "test2"); + } + + @Test + public void testHasGeoLocations() { + Assert.assertTrue(owner.hasGeoLocations()); + Assert.assertFalse(owner.hasGeoLocations("test1")); + owner.addGeolocations(new GeoLocations("test1")); + Assert.assertTrue(owner.hasGeoLocations()); + Assert.assertTrue(owner.hasGeoLocations("test1")); + owner.addGeolocations(new GeoLocations("test2")); + Assert.assertTrue(owner.hasGeoLocations()); + Assert.assertTrue(owner.hasGeoLocations("test1")); + Assert.assertTrue(owner.hasGeoLocations("test2")); + Assert.assertTrue(owner.hasGeoLocations("test1", "test2")); + } + + @Test + public void testGetGeoLocations1() { + Assert.assertNull(owner.getGeoLocations("test1")); + GeoLocations geoLocations11 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations11); + Assert.assertSame(geoLocations11, owner.getGeoLocations("test1")); + + GeoLocations geoLocations2 = new GeoLocations("test2"); + owner.addGeolocations(geoLocations2); + Assert.assertSame(geoLocations11, owner.getGeoLocations("test1")); + Assert.assertSame(geoLocations2, owner.getGeoLocations("test2")); + + GeoLocations geoLocations12 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations12); + Assert.assertNotNull(owner.getGeoLocations("test1")); + Assert.assertSame(geoLocations2, owner.getGeoLocations("test2")); + + } + + @Test + public void testGetGeoLocationsN() { + GeoLocations geoLocations11 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations11); + Assert.assertEquals(0, owner.getGeoLocations().size()); + check(owner.getGeoLocations(new String[]{"test1"}), geoLocations11); + check(owner.getGeoLocations((String[]) null), geoLocations11); + + GeoLocations geoLocations2 = new GeoLocations("test2"); + owner.addGeolocations(geoLocations2); + Assert.assertEquals(0, owner.getGeoLocations().size()); + check(owner.getGeoLocations(new String[]{"test1"}), geoLocations11); + check(owner.getGeoLocations(new String[]{"test2"}), geoLocations2); + check(owner.getGeoLocations((String[]) null), true, geoLocations11, geoLocations2); + + GeoLocations geoLocations12 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations12); + Assert.assertEquals(0, owner.getGeoLocations().size()); + check(owner.getGeoLocations(new String[]{"test1"}), true, geoLocations11, geoLocations12); + Assert.assertEquals(1, owner.getGeoLocations(new String[]{"test2"}).size()); + check(owner.getGeoLocations((String[]) null), true, geoLocations11, geoLocations2, geoLocations12); + } + + @Test + public void testRemoveGeoLocationsN() { + GeoLocations geoLocations11 = new GeoLocations("test1"), geoLocations2 = new GeoLocations("test2"), geoLocations12 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations11); + owner.addGeolocations(geoLocations2); + owner.addGeolocations(geoLocations12); + Assert.assertEquals(3, owner.getGeoLocations((String[]) null).size()); + owner.removeGeolocations("test1"); + check(owner.getGeoLocations((String[]) null), true, geoLocations2); + owner.removeGeolocations("test2"); + Assert.assertEquals(0, owner.getGeoLocations((String[]) null).size()); + } + + @Test + public void testRemoveGeoLocations1() { + GeoLocations geoLocations11 = new GeoLocations("test1"), geoLocations2 = new GeoLocations("test2"), geoLocations12 = new GeoLocations("test1"); + owner.addGeolocations(geoLocations11); + owner.addGeolocations(geoLocations2); + owner.addGeolocations(geoLocations12); + Assert.assertEquals(3, owner.getGeoLocations((String[]) null).size()); + owner.removeGeolocations(geoLocations11); + check(owner.getGeoLocations((String[]) null), true, geoLocations12, geoLocations2); + owner.removeGeolocations(geoLocations2); + check(owner.getGeoLocations((String[]) null), geoLocations12); + owner.removeGeolocations(geoLocations12); + Assert.assertEquals(0, owner.getGeoLocations((String[]) null).size()); + } +} 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/GeoLocationsStreamPersistenceTest.java similarity index 92% rename from tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java rename to tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsStreamPersistenceTest.java index 7f2fc27..2eaa8a8 100644 --- 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/GeoLocationsStreamPersistenceTest.java @@ -2,6 +2,8 @@ package tdt4140.gr1800.app.core; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -12,9 +14,9 @@ import org.junit.Test; import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; -public class GeoLocationsPersistenceTest { +public class GeoLocationsStreamPersistenceTest { - private GeoLocationsPersistence persistence; + private GeoLocationsStreamPersistence persistence; @Before public void setUp() { diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java index 689aaee..c03b9e5 100644 --- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java @@ -67,7 +67,7 @@ public class GeoLocationsTest extends TimedTaggedTest { } @Test - public void testFindLocationsNearby() { + public void testFindLocationsNearby() { LatLong latLong = new LatLong(0, 0); Assert.assertTrue(geoLocations.findLocationsNearby(latLong, 0).isEmpty()); geoLocations.addLocation(latLong); diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/TimedTaggedTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/TimedTaggedTest.java index 1e16bc4..65b1ce6 100644 --- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/TimedTaggedTest.java +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/TimedTaggedTest.java @@ -3,6 +3,7 @@ package tdt4140.gr1800.app.core; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.Arrays; import org.junit.Assert; import org.junit.Before; @@ -43,6 +44,42 @@ public class TimedTaggedTest { Assert.assertEquals(now.toLocalTime(), timedTagged.getTime()); } + @Test + public void testTaggedValueOf() { + Assert.assertEquals("<en, to>", TimedTaggedImpl.valueOf("en; to", "; ").getTags("<", ", ", ">")); + Assert.assertEquals("<en, to>", TimedTaggedImpl.valueOf("en,to").getTags("<", ", ", ">")); + } + + @Test + public void testTaggedSet() { + timedTagged.setTags("en", "to"); + Assert.assertTrue(timedTagged.hasTags("en")); + Assert.assertTrue(timedTagged.hasTags("to")); + timedTagged.setTags("tre"); + Assert.assertFalse(timedTagged.hasTags("en")); + Assert.assertFalse(timedTagged.hasTags("to")); + Assert.assertTrue(timedTagged.hasTags("tre")); + } + + @Test + public void testTaggedGet() { + Assert.assertEquals(0, timedTagged.getTags().length); + timedTagged.setTags("en", "to", "to"); + String[] tags = timedTagged.getTags(); + Assert.assertEquals(2, tags.length); + Arrays.sort(tags); + Arrays.equals(new String[] {"en", "to"}, tags); + } + + @Test + public void testTaggedGet2() { + Assert.assertEquals("", timedTagged.getTags(null, null, null)); + Assert.assertEquals("<>", timedTagged.getTags("<", null, ">")); + timedTagged.setTags("en", "to", "to"); + Assert.assertEquals("ento", timedTagged.getTags(null, null, null)); + Assert.assertEquals("<en, to>", timedTagged.getTags("<", ", ", ">")); + } + @Test public void testTaggedAdd() { timedTagged.addTags("en", "to"); diff --git a/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java b/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java index b31cb41..2cd683e 100644 --- a/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java +++ b/tdt4140-gr1800/app.ui/src/test/java/tdt4140/gr1800/app/ui/FxAppTest.java @@ -7,7 +7,6 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.Assert; @@ -18,7 +17,6 @@ import org.testfx.framework.junit.ApplicationTest; import org.testfx.util.WaitForAsyncUtils; import fxmapcontrol.MapBase; -import fxmapcontrol.MapItemsControl; import javafx.collections.ObservableList; import javafx.fxml.FXMLLoader; import javafx.scene.Node; diff --git a/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java b/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java index 77b0534..9c00904 100644 --- a/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java +++ b/tdt4140-gr1800/web.server/src/main/java/tdt4140/gr1800/web/server/GeoServlet.java @@ -14,12 +14,12 @@ import javax.servlet.http.HttpServletResponse; import io.jenetics.jpx.Person; import tdt4140.gr1800.app.core.GeoLocations; -import tdt4140.gr1800.app.core.GeoLocationsPersistence; +import tdt4140.gr1800.app.core.GeoLocationsStreamPersistence; import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; public class GeoServlet extends HttpServlet { - private GeoLocationsPersistence persistence = new GeoLocationsJsonPersistence(); + private GeoLocationsStreamPersistence persistence = new GeoLocationsJsonPersistence(); private Collection<GeoLocations> allGeoLocations = new ArrayList<GeoLocations>(); @@ -40,6 +40,18 @@ public class GeoServlet extends HttpServlet { super.init(); } + // REST URL structure, according to https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/ + // persons/<id>/geoLocations/<num>/geoLocations/<num> + + // GET variants + // persons: Get all Person objects. Do we allow that? Should we return a list of <id> values or all the person entities (with some subset of properties) + // persons/<id>: Get a specific Person object + // persons/name or email: Get a specific Person object, with the provided name or email (with a '@') + // persons/<id>/geoLocations: Get all the GeoLocations objects, with (some subset of) properties + // persons/<id>/geoLocations/<num>: Get a specific GeoLocations object + // persons/<id>/geoLocations/<num>/geoLocations: Get all GeoLocation objects, with (some subset of) properties + // persons/<id>/geoLocations/<num>/geoLocations/<num>: Get a specific GeoLocations object + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getPathInfo(); Collection<GeoLocations> geoLocations = null; @@ -66,4 +78,45 @@ public class GeoServlet extends HttpServlet { } } } + + // POST variants + // persons: Create a new Person object, with properties in the payload + // persons/<id>: Not allowed + // persons/<id>/geoLocations: Create a new GeoLocations object, with properties in the payload + // persons/<id>/geoLocations/<num>: Not allowed + // persons/<id>/geoLocations/<num>/geoLocations: Create a new GeoLocation object, with properties in the payload + // persons/<id>/geoLocations/<num>/geoLocations/<num>: Not allowed + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doPost(req, resp); + } + + // PUT variants + // persons: Not allowed + // persons/<id>: Update specific Person object + // persons/<id>/geoLocations: Not allowed + // persons/<id>/geoLocations/<num>: Update specific GeoLocations object + // persons/<id>/geoLocations/<num>/geoLocations: Not allowed + // persons/<id>/geoLocations/<num>/geoLocations/<num>: Update specific GeoLocations object + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + // TODO Auto-generated method stub + super.doPut(req, resp); + } + + // DELETE variants + // persons: Not allowed + // persons/<id>: Delete specific Person object + // persons/<id>/geoLocations: Delete all GeoLocations objects? + // persons/<id>/geoLocations/<num>: Delete specific GeoLocations object + // persons/<id>/geoLocations/<num>/geoLocations: Delete all GeoLocation objects? + // persons/<id>/geoLocations/<num>/geoLocations/<num>: Delete specific GeoLocation object + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + // TODO Auto-generated method stub + super.doDelete(req, resp); + } } diff --git a/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java b/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java index 3d00904..a230c44 100644 --- a/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java +++ b/tdt4140-gr1800/web.server/src/test/java/tdt4140/gr1800/web/server/GeoLocationsServerIT.java @@ -10,13 +10,13 @@ import org.junit.Test; import tdt4140.gr1800.app.core.GeoLocated; import tdt4140.gr1800.app.core.GeoLocations; -import tdt4140.gr1800.app.core.GeoLocationsPersistence; +import tdt4140.gr1800.app.core.GeoLocationsStreamPersistence; import tdt4140.gr1800.app.core.LatLong; import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; public class GeoLocationsServerIT { - private GeoLocationsPersistence persistence = new GeoLocationsJsonPersistence(); + private GeoLocationsStreamPersistence persistence = new GeoLocationsJsonPersistence(); private Collection<GeoLocations> get(String path, int size) throws Exception { URL url = new URL("http://localhost:8080/geo" + path); -- GitLab