Skip to content
Snippets Groups Projects
Commit d90b5fc6 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

REST-api og server. Mer javadoc.

parent b01b0369
No related branches found
No related tags found
No related merge requests found
Pipeline #48580 passed
Showing
with 306 additions and 111 deletions
package simpleex.core;
/**
* Represents a geo-location as a latitude, longitude pair.
* @author hal
*
*/
public class LatLong {
public static final String SEPARATOR = ",";
......@@ -7,16 +12,29 @@ public class LatLong {
private final double latitude;
private final double longitude;
/**
* Initialize a LatLong with provided latitude and longitude.
* @param latitude the latitude
* @param longitude the longitude
*/
public LatLong(final double latitude, final double longitude) {
super();
this.latitude = latitude;
this.longitude = longitude;
}
/**
* Gets the latitude.
* @return the latitude
*/
public double getLatitude() {
return latitude;
}
/**
* Gets the longitude.
* @return the longitude
*/
public double getLongitude() {
return longitude;
}
......@@ -49,10 +67,23 @@ public class LatLong {
&& Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude));
}
/**
* Creates a LatLong object from a String.
* The format is <latitude>,<longitude>.
* @param s the String to parse
* @return the new LatLong object
*/
public static LatLong valueOf(final String s) {
return valueOf(s, SEPARATOR);
}
/**
* Creates a LatLong object from a String, using a specific separator.
* The format is <latitude><separator><longitude>.
* @param s
* @param sep
* @return
*/
public static LatLong valueOf(final String s, final String sep) {
final int pos = s.indexOf(sep);
if (pos < 0) {
......@@ -103,10 +134,21 @@ public class LatLong {
return dist;
}
/**
* Computes the distance in meters between two LatLong objects.
* @param latLong1 the first LatLong
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public static double distance(final LatLong latLong1, final LatLong latLong2) {
return distance(latLong1.latitude, latLong1.longitude, latLong2.latitude, latLong2.longitude);
}
/**
* Computes the distance in meters between this LatLong and an other one.
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public double distance(final LatLong latLong2) {
return distance(latitude, longitude, latLong2.latitude, latLong2.longitude);
}
......
......@@ -6,3 +6,7 @@ allprojects {
}
}
}
subprojects {
ext.depVersions = ['jackson': '2.9.8']
}
......@@ -2,15 +2,6 @@
Dette prosjektet inneholder domene- og persistenslagene for [simpleexample2](../README.md).
## Organisering av koden
Prosjektet er organisert med 2 * 2 = 4 kildekodemapper, kode og ressurser for henholdsvis applikasjonen selv og testene:
- **src/main/java** for koden til applikasjonen
- **src/main/resources** for tilhørende ressurser, f.eks. data-filer, som brukes av applikasjonen.
- **src/test/java** for testkoden
- **src/test/resources** for tilhørende ressurser, f.eks. data-filer, som brukes av testene.
## Domenelaget
Domenelaget inneholder alle klasser og logikk knyttet til dataene som applikasjonen handler om og håndterer. Dette laget skal være helt uavhengig av brukergrensesnittet eller lagingsteknikken som brukes.
......
......@@ -42,7 +42,7 @@ checkstyle {
dependencies {
// persistens
// api means that those consuming our library 'inherits' this as a compile dependency
api 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
api "com.fasterxml.jackson.core:jackson-databind:${depVersions.jackson}"
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
......
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package core;
public class Library {
public boolean someLibraryMethod() {
return true;
}
}
package simpleex.core;
/**
* Represents a geo-location as a latitude, longitude pair.
* @author hal
*
*/
public class LatLong {
/**
* The default separator for the valueOf method.
*/
public static final String SEPARATOR = ",";
private final double latitude;
private final double longitude;
/**
* Initialize a LatLong with provided latitude and longitude.
* @param latitude the latitude
* @param longitude the longitude
*/
public LatLong(final double latitude, final double longitude) {
super();
this.latitude = latitude;
this.longitude = longitude;
}
/**
* Gets the latitude.
* @return the latitude
*/
public double getLatitude() {
return latitude;
}
/**
* Gets the longitude.
* @return the longitude
*/
public double getLongitude() {
return longitude;
}
......@@ -49,10 +70,23 @@ public class LatLong {
&& Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude));
}
/**
* Creates a LatLong object from a String.
* The format is &lt;latitude&gt;,&lt;longitude&gt;.
* @param s the String to parse
* @return the new LatLong object
*/
public static LatLong valueOf(final String s) {
return valueOf(s, SEPARATOR);
}
/**
* Creates a LatLong object from a String, using a specific separator.
* The format is &lt;latitude&gt;&lt;separator&gt;&lt;longitude&gt;.
* @param s the String to parse
* @param sep the separator
* @return the new LatLong object
*/
public static LatLong valueOf(final String s, final String sep) {
final int pos = s.indexOf(sep);
if (pos < 0) {
......@@ -64,28 +98,32 @@ public class LatLong {
return new LatLong(lat, lon);
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: : */
/* :: This routine calculates the distance between two points (given the : */
/* :: latitude/longitude of those points). It is being used to calculate : */
/* :: the distance between two locations using GeoDataSource (TM) products : */
/* :: : */
/* :: Definitions: : */
/* :: South latitudes are negative, east longitudes are positive : */
/* :: : */
/* :: Passed to function: : */
/* :: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) : */
/* :: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) : */
/* :: Worldwide cities and other features databases with latitude longitude : */
/* :: are available at http://www.geodatasource.com : */
/* :: : */
/* :: For enquiries, please contact sales@geodatasource.com : */
/* :: : */
/* :: Official Web site: http://www.geodatasource.com : */
/* :: : */
/* :: GeoDataSource.com (C) All Rights Reserved 2015 : */
/* :: : */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/**
* This routine calculates the distance between two points (given the
* latitude/longitude of those points). It is being used to calculate
* the distance between two locations using GeoDataSource (TM) products
*
* <p>Definitions:
* South latitudes are negative, east longitudes are positive
*
* <p>Passed to function:
* lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)
* lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)
* Worldwide cities and other features databases with latitude longitude
* are available at http://www.geodatasource.com
*
* <p>For enquiries, please contact sales@geodatasource.com
*
* <p>Official Web site: http://www.geodatasource.com
*
* <p>GeoDataSource.com (C) All Rights Reserved 2015
*
* @param lat1 the latitude of the first point
* @param lon1 the longitude of the first point
* @param lat2 the latitude of the other point
* @param lon2 the longitude of the other point
* @return
*/
public static double distance(final double lat1, final double lon1, final double lat2,
final double lon2) {
if (lon1 == lon2 && lat1 == lat2) {
......@@ -103,24 +141,39 @@ public class LatLong {
return dist;
}
/**
* Computes the distance in meters between two LatLong objects.
* @param latLong1 the first LatLong
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public static double distance(final LatLong latLong1, final LatLong latLong2) {
return distance(latLong1.latitude, latLong1.longitude, latLong2.latitude, latLong2.longitude);
}
/**
* Computes the distance in meters between this LatLong and an other one.
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public double distance(final LatLong latLong2) {
return distance(latitude, longitude, latLong2.latitude, latLong2.longitude);
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: This function converts decimal degrees to radians : */
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/**
* This function converts decimal degrees to radians.
* @param deg the desimal degrees
* @return the corresponding radians
*/
private static double deg2rad(final double deg) {
return (deg * Math.PI / 180.0);
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: This function converts radians to decimal degrees : */
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/**
* This function converts radians to decimal degrees.
* @param rad the radians
* @return the corresponding decimal degrees
*/
private static double rad2deg(final double rad) {
return (rad * 180 / Math.PI);
}
......
......@@ -5,20 +5,40 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* Represents a sequence of LatLong objects.
* @author hal
*
*/
public class LatLongs implements Iterable<LatLong> {
final List<LatLong> latLongs = new ArrayList<>();
private final List<LatLong> latLongs = new ArrayList<>();
/**
* Initializes an empty LatLongs object.
*/
public LatLongs() {}
/**
* Initializes a LatLongs object with the provided latitude, longitude pairs.
* @param latLongsArray the latitude, longitude pairs
*/
public LatLongs(final double... latLongsArray) {
addLatLongs(latLongsArray);
}
/**
* Initializes a LatLongs object with the provided LatLong objects.
* @param latLongs the LatLong objects
*/
public LatLongs(final LatLong... latLongs) {
addLatLongs(latLongs);
}
/**
* Initializes a LatLongs object with the provided LatLong objects.
* @param latLongs the LatLong objects
*/
public LatLongs(final Collection<LatLong> latLongs) {
addLatLongs(latLongs);
}
......@@ -28,34 +48,68 @@ public class LatLongs implements Iterable<LatLong> {
return latLongs.iterator();
}
/**
* Gets the number of LatLong objects.
* @return the number of LatLong objects
*/
public int getLatLongCount() {
return latLongs.size();
}
/**
* Gets the LatLong object at the provided position.
* @param num the position of the LatLong object
* @return the LatLong object at the provided position
*/
public LatLong getLatLong(final int num) {
return latLongs.get(num);
}
/**
* Sets the LatLong object at the provided position.
* @param num the position to set
* @param latLong the LatLong object to set at the provided position
*/
public void setLatLong(final int num, final LatLong latLong) {
latLongs.set(num, latLong);
}
/**
* Adds a LatLong object to the end of this LatLongs object.
* @param latLong the LatLong object to append
* @return the position of the newly added LatLong object
*/
public int addLatLong(final LatLong latLong) {
final int pos = latLongs.size();
latLongs.add(latLong);
return pos;
}
/**
* Adds a collection of LatLong object to the end of this LatLongs object.
* @param latLongs the collection of LatLong objects to append
* @return the position where the LatLong objects were added
*/
public final int addLatLongs(final Collection<LatLong> latLongs) {
final int pos = this.latLongs.size();
this.latLongs.addAll(latLongs);
return pos;
}
/**
* Adds a the provided LatLong objects to the end of this LatLongs object.
* @param latLongs the LatLong objects to add
* @return the position where the LatLong objects were added
*/
public final int addLatLongs(final LatLong... latLongs) {
return addLatLongs(List.of(latLongs));
}
/**
* Adds a the provided latitude, longitude pairs to the end of this LatLongs object.
* @param latLongsArray the latitude, longitude pairs
* @return the position where the LatLong objects were added
*/
public final int addLatLongs(final double... latLongsArray) {
final Collection<LatLong> latLongs = new ArrayList<>(latLongsArray.length / 2);
for (int i = 0; i < latLongsArray.length; i += 2) {
......@@ -64,6 +118,11 @@ public class LatLongs implements Iterable<LatLong> {
return addLatLongs(latLongs);
}
/**
* Removes the LatLong object at the provided position.
* @param num the position to remove
* @return the removed LatLong object
*/
public LatLong removeLatLong(final int num) {
return latLongs.remove(num);
}
......
......@@ -10,6 +10,11 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import simpleex.core.LatLong;
/**
* JSON serializer for LatLong.
* @author hal
*
*/
public class LatLongDeserializer extends JsonDeserializer<LatLong> {
private static final int ARRAY_JSON_NODE_SIZE = 2;
......@@ -21,7 +26,12 @@ public class LatLongDeserializer extends JsonDeserializer<LatLong> {
return deserialize(jsonNode);
}
public LatLong deserialize(final JsonNode jsonNode) throws JsonProcessingException {
/**
* Decodes the provided JsonNode to a LatLong object.
* @param jsonNode the JsonNode to decode
* @return the corresponding LatLong object
*/
public LatLong deserialize(final JsonNode jsonNode) {
if (jsonNode instanceof ObjectNode) {
final ObjectNode objectNode = (ObjectNode) jsonNode;
final double latitude = objectNode.get(LatLongSerializer.LATITUDE_FIELD_NAME).asDouble();
......
......@@ -7,6 +7,11 @@ import com.fasterxml.jackson.databind.module.SimpleSerializers;
import simpleex.core.LatLong;
import simpleex.core.LatLongs;
/**
* A Module for LatLongs serialization/deserialization.
* @author hal
*
*/
public class LatLongsModule extends Module {
@Override
......@@ -22,6 +27,9 @@ public class LatLongsModule extends Module {
private final SimpleSerializers serializers = new SimpleSerializers();
private final SimpleDeserializers deserializers = new SimpleDeserializers();
/**
* Initializes the LatLongsModule with appropriate serializers.
*/
public LatLongsModule() {
serializers.addSerializer(LatLong.class, new LatLongSerializer());
serializers.addSerializer(LatLongs.class, new LatLongsSerializer());
......
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package core;
import org.junit.Test;
import static org.junit.Assert.*;
public class LibraryTest {
@Test public void testSomeLibraryMethod() {
Library classUnderTest = new Library();
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
}
}
......@@ -10,6 +10,9 @@ public class LatLongsTest {
private LatLongs latLongs;
/**
* Setup method, running before each test method.
*/
@Before
public void setUp() {
latLongs = new LatLongs();
......
......@@ -9,6 +9,7 @@ import simpleex.core.LatLongs;
public class LatLongsJsonTest {
private final ObjectMapper objectMapper = new ObjectMapper();
{
objectMapper.registerModule(new LatLongsModule());
}
......@@ -18,10 +19,19 @@ public class LatLongsJsonTest {
Assert.assertEquals(expected, actual.replaceAll("\\s+", ""));
}
private LatLong latLong1() {
return new LatLong(63.1, 12.3);
}
private LatLong latLong2() {
return new LatLong(63.0, 12.4);
}
@Test
public void testLatLongsSerialization() throws Exception {
final String actualJson = objectMapper.writeValueAsString(new LatLongs(new LatLong(63.1, 12.3), new LatLong(63.0, 12.4)));
final String expectedJson = "[{\"latitude\":63.1,\"longitude\":12.3},{\"latitude\":63.0,\"longitude\":12.4}]";
final String actualJson = objectMapper.writeValueAsString(new LatLongs(latLong1(), latLong2()));
final String expectedJson = "[{\"latitude\":63.1,\"longitude\":12.3},"
+ "{\"latitude\":63.0,\"longitude\":12.4}]";
assertEqualsIgnoreWhitespace(expectedJson, actualJson);
}
......@@ -30,7 +40,7 @@ public class LatLongsJsonTest {
final String json = "[{\"latitude\":63.1,\"longitude\":12.3}, [63.0,12.4]]";
final LatLongs latLongs = objectMapper.readValue(json, LatLongs.class);
Assert.assertEquals(2, latLongs.getLatLongCount());
Assert.assertEquals(new LatLong(63.1, 12.3), latLongs.getLatLong(0));
Assert.assertEquals(new LatLong(63.0, 12.4), latLongs.getLatLong(1));
Assert.assertEquals(latLong1(), latLongs.getLatLong(0));
Assert.assertEquals(latLong2(), latLongs.getLatLong(1));
}
}
......@@ -2,15 +2,6 @@
Dette prosjektet inneholder brukergrensesnittlaget for [simpleexample2](../README.md).
## Organisering av koden
Prosjektet er organisert med 2 * 2 = 4 kildekodemapper, kode og ressurser for henholdsvis applikasjonen selv og testene:
- **src/main/java** for koden til applikasjonen
- **src/main/resources** for tilhørende ressurser, f.eks. FXML-filer, som brukes av applikasjonen.
- **src/test/java** for testkoden
- **src/test/resources** for tilhørende ressurser, f.eks. FXML-filer, som brukes av testene.
## Brukergrensesnittlaget
Brukergrensesnittlaget inneholder alle klasser og logikk knyttet til visning og handlinger på dataene i domenelaget. Brukergrensesnittet til vår app viser frem en liste av geo-lokasjoner, den som velges vises på et kart. En flytte og legge til geo-lokasjoner. Samlingen med geo-lokasjoner kan lagres og evt. leses inn igjen.
......
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package fxui;
public class Library {
public boolean someLibraryMethod() {
return true;
}
}
......@@ -5,20 +5,37 @@ import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
/**
* Helper controller for handling dragging a map or marker.
* @author hal
*
*/
public class DraggableNodeController {
private final NodeDraggedHandler nodeDraggedHandler;
/**
* Initializes with no NodeDraggedHandler.
*/
public DraggableNodeController() {
this(null);
}
/**
* Initializes with a specific NodeDraggedHandler.
* @param nodeDraggedHandler the NodeDraggedHandler
*/
public DraggableNodeController(final NodeDraggedHandler nodeDraggedHandler) {
this.nodeDraggedHandler = (nodeDraggedHandler != null ? nodeDraggedHandler : (node, x, y) -> {});
final NodeDraggedHandler noOp = (node, x, y) -> {};
this.nodeDraggedHandler = (nodeDraggedHandler != null ? nodeDraggedHandler : noOp);
}
private boolean immediate = false;
/**
* Sets whether feedback is immediate or not.
* @param immediate the new immediate value
*/
public void setImmediate(final boolean immediate) {
this.immediate = immediate;
}
......@@ -31,12 +48,20 @@ public class DraggableNodeController {
private final EventHandler<MouseEvent> mouseDraggedHandler = this::mouseDragged;
private final EventHandler<MouseEvent> mouseReleasedHandler = this::mouseReleased;
/**
* Attaches this controller to the provided Node (e.g. map or marker).
* @param node the Node to attach the controller to
*/
public void attach(final Node node) {
node.setOnMousePressed(mousePressedHandler);
node.setOnMouseDragged(mouseDraggedHandler);
node.setOnMouseReleased(mouseReleasedHandler);
}
/**
* Detaches this controller from the provided Node (e.g. map or marker).
* @param node the Node to detach the controller from
*/
public void detach(final Node node) {
node.setOnMousePressed(null);
node.setOnMouseDragged(null);
......@@ -84,7 +109,18 @@ public class DraggableNodeController {
}
}
/**
* Interface for node drag feedback.
* @author hal
*
*/
public interface NodeDraggedHandler {
public void nodeDragged(Node currentNode2, double dx, double dy);
/**
* Callback for providing feedback during drag.
* @param node the dragged node
* @param dx the relative x movement
* @param dy the relative y movement
*/
public void nodeDragged(Node node, double dx, double dy);
}
}
......@@ -20,6 +20,10 @@ public class FxApp extends Application {
stage.show();
}
/**
* Launches the app.
* @param args the command line arguments
*/
public static void main(final String[] args) {
// only needed on ios
System.setProperty("os.target", "ios");
......
......@@ -44,27 +44,39 @@ FxAppController --> ListView: "locationListView"
@enduml
*/
/**
* The controller for the app.
* @author hal
*
*/
public class FxAppController {
private LatLongs latLongs;
/**
* Initializes the controller.
*/
public FxAppController() {
latLongs = new LatLongs();
}
/**
* Gets the LatLongs objects used by the controller.
* @return the controller's LatLongs objects
*/
public LatLongs getLatLongs() {
return latLongs;
}
// to make it testable
/**
* Sets the LatLongs objects used by the controller.
* @param latLongs the LatLongs object to use
*/
public void setLatLongs(final LatLongs latLongs) {
this.latLongs = latLongs;
updateLocationViewList(0);
}
// @FXML
// private FileMenuController fileMenuController;
@FXML
private ListView<LatLong> locationListView;
......@@ -202,6 +214,10 @@ public class FxAppController {
private ObjectMapper objectMapper;
/**
* Gets the ObjectMapper used by this controller.
* @return the ObjectMapper used by this controller
*/
public ObjectMapper getObjectMapper() {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
......
......@@ -6,8 +6,17 @@ import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import simpleex.core.LatLong;
/**
* A circle map marker.
* @author hal
*
*/
public class MapMarker extends MapItem<LatLong> {
/**
* Initializes the MapMarker with the provided location.
* @param latLong the location
*/
public MapMarker(final LatLong latLong) {
setLocation(latLong);
final Circle circle = new Circle();
......@@ -16,6 +25,10 @@ public class MapMarker extends MapItem<LatLong> {
getChildren().add(circle);
}
/**
* Sets the location of this MapMarker.
* @param latLong the new location
*/
public final void setLocation(final LatLong latLong) {
setLocation(new Location(latLong.getLatitude(), latLong.getLongitude()));
}
......
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package fxui;
import org.junit.Test;
import static org.junit.Assert.*;
public class LibraryTest {
@Test public void testSomeLibraryMethod() {
Library classUnderTest = new Library();
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
}
}
......@@ -22,6 +22,9 @@ import simpleex.core.LatLongs;
public class FxAppTest extends ApplicationTest {
/**
* Setup method for headless tests using monocle.
*/
@BeforeClass
public static void headless() {
if (Boolean.valueOf(System.getProperty("gitlab-ci", "false"))) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment