diff --git a/.gitignore b/.gitignore index 098193d38aa968488888f4e4e112622e9d73bb9d..dfaa205dd6b38ab1f8b9cc25d5cef7386cb0c7b7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ bin/ .project t14-test-images log/ +config.properties # User-specific stuff .idea/**/workspace.xml @@ -79,3 +80,5 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser + +config.properties diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b053587b98b9abee0579207b87f55d4972991cad..5eed0fbd37cde9069dd3158d9cbc173c43d713f3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,11 @@ stages: - build - test +# Cache downloaded dependencies and plugins between builds. +cache: + paths: + - /root/.m2/repository/ + build: stage: build only: diff --git a/config.test.properties b/config.test.properties new file mode 100644 index 0000000000000000000000000000000000000000..e4db66512ba4b4d918189a4d7ebedbc6da3f7b99 --- /dev/null +++ b/config.test.properties @@ -0,0 +1,4 @@ +# Test Database Connection Properties +DB_DRIVER=org.h2.Driver +DB_URL=jdbc:h2:mem:test_db;DB_CLOSE_DELAY=-1 +DB_DIALECT=org.hibernate.dialect.H2Dialect diff --git a/javadoc/NTNU/IDATT1002/database/EntityManagerConfig.html b/javadoc/NTNU/IDATT1002/database/EntityManagerConfig.html index f0727075cd319fa8dde338d76625f16716785ac7..47f7d6594fbb6bd003b91394d18705d552be6820 100644 --- a/javadoc/NTNU/IDATT1002/database/EntityManagerConfig.html +++ b/javadoc/NTNU/IDATT1002/database/EntityManagerConfig.html @@ -124,7 +124,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height")); <li>java.lang.Object</li> <li> <ul class="inheritance"> -<li>NTNU.IDATT1002.database.EntityManagerConfig</li> +<li>NTNU.IDATT1002.Config</li> </ul> </li> </ul> diff --git a/pom.xml b/pom.xml index f409895eb63887dec5a35219fb099f42a6aa5566..aa7c61bb3ff675b078230469ada1fb9a8a53b529 100644 --- a/pom.xml +++ b/pom.xml @@ -38,11 +38,13 @@ <artifactId>hibernate-jpa-2.1-api</artifactId> <version>1.0.2.Final</version> </dependency> + <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.0.Final</version> </dependency> + <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> @@ -69,6 +71,12 @@ <version>13</version> </dependency> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-base</artifactId> + <version>15-ea+2</version> + </dependency> + <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-web</artifactId> @@ -115,6 +123,7 @@ <artifactId>junit</artifactId> <version>4.13</version> </dependency> + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> @@ -135,7 +144,7 @@ <version>1.56</version> </dependency> - <!-- Google Maps API --> + <!-- GMapsFX --> <dependency> <groupId>com.lynden</groupId> <artifactId>GMapsFX</artifactId> @@ -149,6 +158,20 @@ </exclusions> </dependency> + <!-- Google Maps API Client --> + <dependency> + <groupId>com.google.maps</groupId> + <artifactId>google-maps-services</artifactId> + <version>0.11.0</version> + </dependency> + + <!-- JavaFX Controls --> + <dependency> + <groupId>org.controlsfx</groupId> + <artifactId>controlsfx</artifactId> + <version>11.0.0</version> + </dependency> + </dependencies> <build> <plugins> @@ -169,6 +192,10 @@ <configuration> <mainClass>NTNU.IDATT1002.App</mainClass> <executable>${java.home}\bin\java</executable> + <options> + <options>--add-exports</options> + <options>javafx.base/com.sun.javafx.event=org.controlsfx.controls</options> + </options> </configuration> </plugin> @@ -176,6 +203,11 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.0</version> + <configuration> + <systemPropertyVariables> + <config_properties>config.test.properties</config_properties> + </systemPropertyVariables> + </configuration> </plugin> <plugin> diff --git a/src/main/java/NTNU/IDATT1002/App.java b/src/main/java/NTNU/IDATT1002/App.java index 5693e0798588f46a158ff04a866a4ce22fb8d1e3..08a1c6063cfdcc25b9540808a64d57dc044b8513 100644 --- a/src/main/java/NTNU/IDATT1002/App.java +++ b/src/main/java/NTNU/IDATT1002/App.java @@ -26,6 +26,14 @@ public class App extends Application { stage.show(); } + /** + * Shut down GeoApiContext on application stop to gracefully close the connection. + */ + @Override + public void stop(){ + ex.getGeoApiContext().shutdown(); + } + public static void setRoot(String fxml) throws IOException { scene.setRoot(loadFXML(fxml)); } diff --git a/src/main/java/NTNU/IDATT1002/ApplicationState.java b/src/main/java/NTNU/IDATT1002/ApplicationState.java index cc727dcaa48d7e397c8ece1723e2e3f5fff2be11..640517cb58ddd22edd63dc4ff65cbe8d553d4e67 100644 --- a/src/main/java/NTNU/IDATT1002/ApplicationState.java +++ b/src/main/java/NTNU/IDATT1002/ApplicationState.java @@ -1,7 +1,6 @@ package NTNU.IDATT1002; -import NTNU.IDATT1002.database.EntityManagerConfig; import NTNU.IDATT1002.models.User; import NTNU.IDATT1002.repository.UserRepository; @@ -28,7 +27,7 @@ public final class ApplicationState { * Initiate properties and save an anonymous user once. */ static { - EntityManager entityManager = EntityManagerConfig.getEntityManager(); + EntityManager entityManager = Config.getEntityManager(); userRepository = new UserRepository(entityManager); } diff --git a/src/main/java/NTNU/IDATT1002/Config.java b/src/main/java/NTNU/IDATT1002/Config.java new file mode 100644 index 0000000000000000000000000000000000000000..f454f18da2a0fc86291b0c8f317ce38c133f6f20 --- /dev/null +++ b/src/main/java/NTNU/IDATT1002/Config.java @@ -0,0 +1,94 @@ +package NTNU.IDATT1002; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +/** + * Application Configuration Singleton for parsing hibernate persistence properties and Google Maps API key. + * Provides a single global access point to the applications entity manager. + */ +public class Config { + + private static EntityManager entityManager; + private static Map<String, Object> configOverrides = new HashMap<>(); + private static Properties properties = loadProperties(); + private static Logger logger = LoggerFactory.getLogger(Config.class); + + private Config() { + } + + /** + * Load properties from configured properties file. Defaults to config.properties. + * + * @return the properties + */ + private static Properties loadProperties() { + String configFile = System.getProperty("config_properties", "config.properties"); + + Properties environmentProperties = new Properties(); + try (InputStream input = new FileInputStream(configFile)) { + environmentProperties.load(input); + } catch (IOException ex) { + logger.error("[x] Failed to load config properties", ex); + } + + return environmentProperties; + } + + public static String getGoogleApiKey() { + return properties.getProperty("GOOGLE_API_KEY"); + } + + /** + * Retrieve the entity manager instance. + * An entity manager is not created until it is requested. + * + * @return an entity manager instance + */ + public static EntityManager getEntityManager() { + if (entityManager == null) + configureEntityManager(); + + return entityManager; + } + + /** + * Parse properties and create the entity manager + */ + private static void configureEntityManager() { + parseConfigProperties(); + createEntityManager(); + } + + /** + * Parse properties and override config. + */ + private static void parseConfigProperties() { + configOverrides.put("javax.persistence.jdbc.driver", properties.getProperty("DB_DRIVER")); + configOverrides.put("javax.persistence.jdbc.url", properties.get("DB_URL")); + configOverrides.put("javax.persistence.jdbc.user", properties.get("DB_USER")); + configOverrides.put("javax.persistence.jdbc.password", properties.get("DB_PASSWORD")); + configOverrides.put("hibernate.dialect", properties.get("DB_DIALECT")); + } + + + /** + * Create an entity manager with configurations overrides. + */ + private static void createEntityManager() { + EntityManagerFactory emf = Persistence.createEntityManagerFactory("ImageApplication", configOverrides); + entityManager = emf.createEntityManager(); + } + +} diff --git a/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java b/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java index a05ec283cb46a8b055e7a26adf8cf3d0d2f11de3..8dc0bb97fa6f8a28e638b8b25f0ea4f3a2b87371 100644 --- a/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java +++ b/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java @@ -1,6 +1,7 @@ package NTNU.IDATT1002.controllers; -import NTNU.IDATT1002.database.EntityManagerConfig; +import NTNU.IDATT1002.Config; +import com.google.maps.GeoApiContext; import javafx.application.HostServices; import javax.persistence.EntityManager; @@ -14,8 +15,9 @@ import java.util.List; */ public class DataExchange { - private EntityManager entityManager; + private String apiKey; public HostServices hostServices; + private GeoApiContext geoApiContext; private String searchField; private List<File> uploadedFiles; private Long chosenAlbumId; @@ -23,16 +25,28 @@ public class DataExchange { public DataExchange(){ searchField = ""; + apiKey = Config.getGoogleApiKey(); + geoApiContext = new GeoApiContext.Builder() + .apiKey(getApiKey()) + .build(); } public EntityManager getEntityManager() { - return EntityManagerConfig.getEntityManager(); + return Config.getEntityManager(); + } + + public String getApiKey() { + return apiKey; } public HostServices getHostServices() { return hostServices; } + public GeoApiContext getGeoApiContext() { + return geoApiContext; + } + public List<File> getUploadedFiles() { return uploadedFiles; } @@ -49,10 +63,6 @@ public class DataExchange { return chosenImg; } - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - public void setHostServices(HostServices hostServices) { this.hostServices = hostServices; } diff --git a/src/main/java/NTNU/IDATT1002/controllers/ImageMapFactory.java b/src/main/java/NTNU/IDATT1002/controllers/ImageMapFactory.java index 701fa4217d3182da7c4a9254963869caa969bbbd..a1c4c11af6426ae95dc08ab4a73954534d953c58 100644 --- a/src/main/java/NTNU/IDATT1002/controllers/ImageMapFactory.java +++ b/src/main/java/NTNU/IDATT1002/controllers/ImageMapFactory.java @@ -1,5 +1,6 @@ package NTNU.IDATT1002.controllers; +import NTNU.IDATT1002.models.GeoLocation; import NTNU.IDATT1002.models.Image; import com.lynden.gmapsfx.GoogleMapView; import com.lynden.gmapsfx.javascript.object.*; @@ -23,42 +24,14 @@ public class ImageMapFactory { private ImageMapFactory() {} /** - * Create a map from given {@link GoogleMapView} with default options and markers for images in given list. + * Create a map from given {@link GoogleMapView} with default options. * * @param googleMapView the map view to add the map to - * @param images the list of images to place on the map * @return the {@link GoogleMap} created to enable further customization */ - public static GoogleMap createMap(GoogleMapView googleMapView, List<Image> images) { - List<LatLong> locations = getLatLongs(images); - + public static GoogleMap createMap(GoogleMapView googleMapView) { MapOptions mapOptions = getMapOptions(); - GoogleMap googleMap = googleMapView.createMap(mapOptions); - logger.info("[x] Google map created with {} locations", locations.size()); - - List<Marker> markers = getMarkers(locations); - googleMap.addMarkers(markers); - logger.info("[x] {} markers added", markers.size()); - - return googleMap; - } - - - /** - * Get latitude and longitude ({@link LatLong}) values for given images. - * - * @param images the list of images - * @return a list of {@link LatLong} - */ - private static List<LatLong> getLatLongs(List<Image> images) { - return images.stream() - .map(Image::getGeoLocation) - .map(geoLocation -> { - double latitude = Double.parseDouble(geoLocation.getLatitude()); - double longitude = Double.parseDouble(geoLocation.getLongitude()); - return new LatLong(latitude, longitude); - }) - .collect(Collectors.toList()); + return googleMapView.createMap(mapOptions); } /** @@ -81,6 +54,37 @@ public class ImageMapFactory { .zoom(3); } + /** + * Create markers from given images. + * + * @param images the list of images + * @return a list of markers created from the images + */ + public static List<Marker> createMarkers(List<Image> images) { + List<LatLong> locations = getLatLongs(images); + List<Marker> markers = getMarkers(locations); + logger.info("[x] {} markers created", markers.size()); + return markers; + } + + /** + * Get latitude and longitude ({@link LatLong}) values for given images. + * + * @param images the list of images + * @return a list of {@link LatLong} + */ + private static List<LatLong> getLatLongs(List<Image> images) { + return images.stream() + .map(Image::getGeoLocation) + .filter(GeoLocation::hasLatLong) + .map(geoLocation -> { + double latitude = Double.parseDouble(geoLocation.getLatitude()); + double longitude = Double.parseDouble(geoLocation.getLongitude()); + return new LatLong(latitude, longitude); + }) + .collect(Collectors.toList()); + } + /** * Create {@link Marker}s for each location in given list of locations. * @@ -97,4 +101,5 @@ public class ImageMapFactory { }) .collect(Collectors.toList()); } + } diff --git a/src/main/java/NTNU/IDATT1002/controllers/Map.java b/src/main/java/NTNU/IDATT1002/controllers/Map.java index 65274811f52926cf5068dce502fc0195d7bd5184..a0cc06fa5686c09e1c2657045131316a03df4970 100644 --- a/src/main/java/NTNU/IDATT1002/controllers/Map.java +++ b/src/main/java/NTNU/IDATT1002/controllers/Map.java @@ -5,18 +5,29 @@ import NTNU.IDATT1002.models.Album; import NTNU.IDATT1002.models.Image; import NTNU.IDATT1002.service.AlbumService; import NTNU.IDATT1002.service.ImageService; +import com.google.maps.*; +import com.google.maps.model.AutocompletePrediction; +import com.google.maps.model.GeocodingResult; +import com.google.maps.model.LatLng; import com.lynden.gmapsfx.GoogleMapView; import com.lynden.gmapsfx.MapComponentInitializedListener; import com.lynden.gmapsfx.javascript.object.GoogleMap; -import java.util.Optional; +import com.lynden.gmapsfx.javascript.object.LatLong; +import com.lynden.gmapsfx.javascript.object.Marker; +import javafx.application.Platform; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; +import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; +import org.controlsfx.control.textfield.TextFields; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,9 +36,13 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.ResourceBundle; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.stream.Stream; + /** * Controls the buttons and changeable elements on map.fxml, @@ -48,11 +63,22 @@ public class Map implements Initializable, MapComponentInitializedListener { @FXML private GoogleMapView mapView; - private GoogleMap map; + + @FXML + private TextField addressTextField; + + private List<String> autoCompletions = new ArrayList<>(); + + private GoogleMap googleMap; + + private GeoApiContext geoApiContext; + + private StringProperty address = new SimpleStringProperty(); private ImageService imageService; private AlbumService albumService; private ExecutorService executorService = Executors.newCachedThreadPool(); + private static Logger logger = LoggerFactory.getLogger(Map.class); @@ -63,51 +89,54 @@ public class Map implements Initializable, MapComponentInitializedListener { } /** - * Register the api key for Google Maps API and listen for map initialization - * in order to update the view once it has been initialized. + * Initialize {@link GoogleMapView} and {@link GeoApiContext} with required API key. + * Also add listener for map initialization and bind the address text field to a {@link SimpleStringProperty}. * * @param url * @param rb */ @Override public void initialize(URL url, ResourceBundle rb) { - mapView.setKey("AIzaSyB_ox5XC8zYBS__aezKumB-KSgKGUjcRx4"); + mapView.setKey(App.ex.getApiKey()); mapView.addMapInializedListener(this); - } + address.bind(addressTextField.textProperty()); + geoApiContext = App.ex.getGeoApiContext(); + } /** - * Check is there is a current album in dataexchange first and uses images from album to display on map. - * If none is found it proceeds to get all images available and display on map + * Create map an fetch images from the appropriate task and add individual markers for images. */ @Override public void mapInitialized() { - List<Image> albumImages = new ArrayList<>(); - Long currentAlbumId; + googleMap = ImageMapFactory.createMap(mapView); + + Task<List<Image>> fetchImagesTask = getImageListTask(); + executorService.submit(fetchImagesTask); - if(App.ex.getChosenAlbumId() == null) { - executorService.submit(fetchImages); + fetchImagesTask.setOnSucceeded(workerStateEvent -> { + List<Image> images = fetchImagesTask.getValue(); + List<Marker> markers = ImageMapFactory.createMarkers(images); + googleMap.addMarkers(markers); + }); + } - fetchImages.setOnSucceeded(workerStateEvent -> { - List<Image> allImages = fetchImages.getValue(); - ImageMapFactory.createMap(mapView, allImages); - }); - } - else { - currentAlbumId = App.ex.getChosenAlbumId(); - Optional<Album> optionalAlbum = albumService.getAlbumById(currentAlbumId); - if (optionalAlbum.isPresent()) { - Album album = optionalAlbum.get(); - albumImages = album.getImages(); - } - ImageMapFactory.createMap(mapView, albumImages); - } + /** + * Decide which images to fetch. Fetch album images if user is trying to view album, else all images. + * + * @return a task which fetches images + */ + private Task<List<Image>> getImageListTask() { + if (App.ex.getChosenAlbumId() == null) + return fetchAllImages; + + return fetchAlbumImages; } /** * Background task for fetching all images. */ - private Task<List<Image>> fetchImages = new Task<>() { + private Task<List<Image>> fetchAllImages = new Task<>() { @Override protected List<Image> call() { try { @@ -120,7 +149,103 @@ public class Map implements Initializable, MapComponentInitializedListener { }; /** - * Change scene to Main page + * Background task for fetching all images in the current chosen album + * in {@link DataExchange}. + */ + private Task<List<Image>> fetchAlbumImages = new Task<>() { + @Override + protected List<Image> call() { + try { + Optional<Album> optionalAlbum = albumService.getAlbumById(App.ex.getChosenAlbumId()); + + if (optionalAlbum.isPresent()) + return optionalAlbum.get().getImages(); + + } catch (Exception e) { + logger.error("[x] Failed to fetch images", e); + } + return new ArrayList<>(); + } + }; + + /** + * Query for autocomplete predictions and bind them to the corresponding text field. + * + * @param keyEvent + */ + public void queryAutocomplete(KeyEvent keyEvent) { + QueryAutocompleteRequest queryAutocompleteRequest = PlacesApi.queryAutocomplete(geoApiContext, address.get()); + + queryAutocompleteRequest.setCallback(new PendingResult.Callback<>() { + @Override + public void onResult(AutocompletePrediction[] autocompletePredictions) { + autoCompletions = Stream.of(autocompletePredictions) + .map(prediction -> prediction.description) + .collect(Collectors.toList()); + + TextFields.bindAutoCompletion(addressTextField, autoCompletions); + } + + @Override + public void onFailure(Throwable e) { + logger.error("[x] Failed to fetch predictions. Query='{}'", address.get(), e); + } + }); + } + + /** + * Search a Geocoding address with the current input in the address search text field. + * Centers the map on the first result. + * + * @param event + */ + public void searchGeocodingAddress(ActionEvent event) { + GeocodingApiRequest geoCodingAddressRequest = GeocodingApi.newRequest(geoApiContext).address(address.get()); + + geoCodingAddressRequest.setCallback(new PendingResult.Callback<>() { + @Override + public void onResult(GeocodingResult[] result) { + LatLng firstLatLngFound = result[0].geometry.location; + logger.info("[x] Geocoding result found: {}", result[0].formattedAddress); + + Platform.runLater(() -> centerMapOnLocation(firstLatLngFound)); + } + + @Override + public void onFailure(Throwable e) { + logger.error("[x] Failed to fetch Geocoding locations", e); + if (e instanceof ArrayIndexOutOfBoundsException) + Platform.runLater(() -> showInfoAlert("No locations found")); + else + Platform.runLater(() -> showInfoAlert("Oops, an error occurred while searching.")); + } + }); + } + + /** + * Center map on given {@link LatLng} and set appropriate zoom level. + * + * @param latLng the location to center on + */ + private void centerMapOnLocation(LatLng latLng) { + LatLong newLatLong = new LatLong(latLng.lat, latLng.lng); + googleMap.setCenter(newLatLong); + googleMap.setZoom(10); + } + + /** + * Show an info alert to the user with given message. + * + * @param message the message containing info to the user + */ + private void showInfoAlert(String message) { + Alert alert = new Alert(Alert.AlertType.INFORMATION, message); + alert.show(); + } + + /** + * Change scene to Main page. + * * @param mouseEvent * @throws IOException */ @@ -131,7 +256,8 @@ public class Map implements Initializable, MapComponentInitializedListener { /** * Change scene to Search page. It reads the value of the search - * field and if not empty it is passed to dataexchange + * field and if not empty it is passed to dataexchange. + * * @param actionEvent * @throws IOException */ @@ -145,6 +271,7 @@ public class Map implements Initializable, MapComponentInitializedListener { /** * Change scene to Explore page + * * @param actionEvent * @throws IOException */ @@ -185,13 +312,5 @@ public class Map implements Initializable, MapComponentInitializedListener { App.setRoot("upload"); } - /** - * Search for images on a specific place. - * - * @param actionEvent - */ - public void MapSearch(ActionEvent actionEvent) { - //TODO: Make method - } } diff --git a/src/main/java/NTNU/IDATT1002/database/EntityManagerConfig.java b/src/main/java/NTNU/IDATT1002/database/EntityManagerConfig.java deleted file mode 100644 index 22d6059a579179ba1945809e05bb7c9fab33a5cc..0000000000000000000000000000000000000000 --- a/src/main/java/NTNU/IDATT1002/database/EntityManagerConfig.java +++ /dev/null @@ -1,97 +0,0 @@ -package NTNU.IDATT1002.database; - -import org.hibernate.cfg.Environment; - -import javax.persistence.*; -import java.util.*; - - -/** - * Entity Manager Configuration Singleton for overriding hibernate persistence properties. - * Provides a single global access point to the applications entity manager. - */ -public class EntityManagerConfig { - - private static EntityManager entityManager; - private static Map<String, Object> configOverrides = new HashMap<>(); - private static Properties properties = Environment.getProperties(); - - - private EntityManagerConfig() { - } - - /** - * Retrieve the entity manager instance. - * An entity manager is not created until it is requested. - * - * @return an entity manager instance - */ - public static EntityManager getEntityManager() { - if (entityManager == null) - configureEntityManager(); - - return entityManager; - } - - /** - * Parse properties and create the entity manager - */ - private static void configureEntityManager() { - if (shouldOverrideConfig()) - parseConfigProperties(); - - createEntityManager(); - } - - private static boolean shouldOverrideConfig() { - return Boolean.parseBoolean((String) properties.get("OVERRIDE_DEFAULT_DB_CONFIG")); - } - - /** - * Parse properties from resources/hibernate.properties and overrides found values. - */ - private static void parseConfigProperties() { - Set<Object> envKeys = properties.keySet(); - - for (Object key : envKeys) - parseProperty(key); - } - - /** - * Parse desired values from given key in properties and add them to the configuration overrides. - * - * @param key the key to parse - */ - private static void parseProperty(Object key) { - switch ((String) key) { - case "DB_DRIVER": - configOverrides.put("javax.persistence.jdbc.driver", properties.get(key)); - break; - case "DB_URL": - configOverrides.put("javax.persistence.jdbc.url", properties.get(key)); - break; - case "DB_USER": - configOverrides.put("javax.persistence.jdbc.user", properties.get(key)); - break; - case "DB_PASSWORD": - configOverrides.put("javax.persistence.jdbc.password", properties.get(key)); - break; - case "DB_DIALECT": - configOverrides.put("hibernate.dialect", properties.get(key)); - break; - case "DB_HBM2DDL": - configOverrides.put("hibernate.hbm2ddl.auto", properties.get(key)); - break; - default: - break; - } - } - - /** - * Create an entity manager with configurations overrides. - */ - private static void createEntityManager() { - EntityManagerFactory emf = Persistence.createEntityManagerFactory("ImageApplication", configOverrides); - entityManager = emf.createEntityManager(); - } -} diff --git a/src/main/java/NTNU/IDATT1002/database/LoadDatabase.java b/src/main/java/NTNU/IDATT1002/database/LoadDatabase.java index 4710eff43d08e72b0992e364dffb9b4f16106786..cff8693eefe5f16b79e202b2a04813f863ca7323 100644 --- a/src/main/java/NTNU/IDATT1002/database/LoadDatabase.java +++ b/src/main/java/NTNU/IDATT1002/database/LoadDatabase.java @@ -1,5 +1,6 @@ package NTNU.IDATT1002.database; +import NTNU.IDATT1002.Config; import NTNU.IDATT1002.models.Image; import NTNU.IDATT1002.models.Tag; import NTNU.IDATT1002.models.User; @@ -24,7 +25,7 @@ public class LoadDatabase { private static ImageService imageService; static { - EntityManager entityManager = EntityManagerConfig.getEntityManager(); + EntityManager entityManager = Config.getEntityManager(); userService = new UserService(entityManager); albumService = new AlbumService(entityManager); diff --git a/src/main/java/NTNU/IDATT1002/models/GeoLocation.java b/src/main/java/NTNU/IDATT1002/models/GeoLocation.java index a52ad8319ed68788d6d43d0272e013cc178692a4..63f11c73a9f6e900cdb1d2f66608b0bcb6ea16ae 100644 --- a/src/main/java/NTNU/IDATT1002/models/GeoLocation.java +++ b/src/main/java/NTNU/IDATT1002/models/GeoLocation.java @@ -58,10 +58,6 @@ public class GeoLocation { return longitude; } - public void setGeoLocationId(Long geoLocationId) { - this.geoLocationId = geoLocationId; - } - public void setLatitude(String altitude) { this.latitude = altitude; } @@ -74,6 +70,15 @@ public class GeoLocation { this.metadata = metadata; } + /** + * Verify that this geolocation has latitude and longitude different from 0. + * + * @return whether latitude and longitude are different from 0. + */ + public boolean hasLatLong() { + return Double.parseDouble(latitude) != 0 && Double.parseDouble(longitude) != 0; + } + @Override public String toString() { return "GeoLocation{" + diff --git a/src/main/java/NTNU/IDATT1002/service/UserService.java b/src/main/java/NTNU/IDATT1002/service/UserService.java index 3bc5d4eabaad6533893edabb2517018a4b348245..532eadd4368ae9db065f07621de10f74e82f2e4a 100644 --- a/src/main/java/NTNU/IDATT1002/service/UserService.java +++ b/src/main/java/NTNU/IDATT1002/service/UserService.java @@ -7,10 +7,10 @@ import NTNU.IDATT1002.repository.LoginRepository; import NTNU.IDATT1002.repository.UserRepository; import NTNU.IDATT1002.utils.Authentication; -import java.util.List; import javax.persistence.EntityManager; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Optional; /** diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 86ad1d585b7324862355d4a00296f010793ae399..7ff7ec019669b0df83a571d9d96a168d97873b8b 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -17,11 +17,6 @@ <class>NTNU.IDATT1002.models.GeoLocation</class> <properties> - <!-- Configuring JDBC properties --> - <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:mysql://mysql.stud.iie.ntnu.no:3306/g_sysutv_14" /> - <property name="javax.persistence.jdbc.user" value="g_sysutv_14" /> - <property name="javax.persistence.jdbc.password" value="tNdTRrwM" /> <!-- Hibernate properties --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/> diff --git a/src/main/resources/NTNU/IDATT1002/map.fxml b/src/main/resources/NTNU/IDATT1002/map.fxml index 8b71e37754e8d622c124b32dd2de2326fd77060d..994b816e731d40dab7670ac5f579cc373c926c54 100644 --- a/src/main/resources/NTNU/IDATT1002/map.fxml +++ b/src/main/resources/NTNU/IDATT1002/map.fxml @@ -61,12 +61,12 @@ <Font name="System Bold" size="24.0" /> </font> </Text> - <TextField fx:id="search" prefHeight="44.0" prefWidth="664.0" promptText="Search for your location"> + <TextField fx:id="addressTextField" onKeyPressed="#queryAutocomplete" onAction="#searchGeocodingAddress" prefHeight="44.0" prefWidth="664.0" promptText="Search for your location"> <font> <Font size="18.0" /> </font> </TextField> - <Button fx:id="searchBtn" mnemonicParsing="false" onAction="#MapSearch" prefHeight="44.0" prefWidth="99.0" text="SEARCH"> + <Button fx:id="searchBtn" mnemonicParsing="false" onAction="#searchGeocodingAddress" prefHeight="44.0" prefWidth="99.0" text="GO"> <font> <Font size="18.0" /> </font> diff --git a/src/main/resources/hibernate.properties b/src/main/resources/hibernate.properties deleted file mode 100644 index 1c3c5a0e157d86a48cb83f91363d52030ca119a5..0000000000000000000000000000000000000000 --- a/src/main/resources/hibernate.properties +++ /dev/null @@ -1,10 +0,0 @@ -# Set this value to true if you want to configure another connection -OVERRIDE_DEFAULT_DB_CONFIG=false - -# These values correspond to database hosted on https://www.digitalocean.com/ -DB_DRIVER=com.mysql.cj.jdbc.Driver -DB_URL=jdbc:mysql://db-mysql-lon1-07155-do-user-7212587-0.a.db.ondigitalocean.com:25060/image_application -DB_USER=doadmin -DB_PASSWORD=s4oxtqu20e8r7tx5 -DB_DIALECT=org.hibernate.dialect.MySQL8Dialect -DB_HBM2DDL=update \ No newline at end of file diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index 1292de038e0fa99c3a4fc9aacac92c969b8076f1..5275d466e056aec80d85aac13aa7f1d814a7923d 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -14,7 +14,6 @@ <class>NTNU.IDATT1002.models.Album</class> <class>NTNU.IDATT1002.models.Metadata</class> <class>NTNU.IDATT1002.models.Tag</class> - <class>NTNU.IDATT1002.models.Histogram</class> <class>NTNU.IDATT1002.models.GeoLocation</class> <properties>