Skip to content
Snippets Groups Projects
Commit 092d7144 authored by Rhys Nute's avatar Rhys Nute
Browse files

Merge branch 'main' of https://git.cardiff.ac.uk/d1634883/client-project into...

Merge branch 'main' of https://git.cardiff.ac.uk/d1634883/client-project into 74-as-a-user-i-want-to-see-a-page-of-local-authorities-so-that-i-can-easily-source-contact-details

# Conflicts:
#	src/main/resources/data.sql
#	src/main/resources/schema.sql
#	src/main/resources/templates/fragments/Templating.html
parents 65fb5939 6a4491e8
Branches
No related tags found
1 merge request!31Resolve "As a user, I want to see a page of local authorities so that I can easily source contact details for a variety of different local authorities."
Showing
with 592 additions and 87 deletions
......@@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
id "com.github.node-gradle.node" version "7.0.1"
}
group = 'Team.5'
......@@ -26,7 +27,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.mariadb.jdbc:mariadb-java-client:2.1.2'
testImplementation 'junit:junit:4.13.1'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'junit:junit:4.13.1'
compileOnly 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok:1.18.28'
compileOnly 'org.projectlombok:lombok'
......@@ -34,12 +36,23 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE'
// https://mvnrepository.com/artifact/org.webjars/openlayers
implementation group: 'org.webjars', name: 'openlayers', version: '5.2.0'
}
tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
}
test {
useJUnitPlatform()
}
tasks.named('test') {
useJUnitPlatform()
}
task myScript(type: NodeTask) {
script = file('src/main/resources/static/scripts/mapAPI.js')
}
File deleted
//Implements the locations repository using JDBC
package Team5.SmartTowns.Data;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class locationRepositoryJDBC implements locationRepository {
private JdbcTemplate jdbc;
private RowMapper<Location> locationMapper;
public locationRepositoryJDBC(JdbcTemplate aJdbc) {
this.jdbc = aJdbc;
setlocationMapper();
}
private void setlocationMapper(){
locationMapper = (rs, i) -> new Location(
rs.getString("locationName"),
rs.getString("locationEmail"),
rs.getString("locationDescription"),
rs.getString("locationPlace"),
rs.getInt("locationTrailID")
);
}
public List<Location> getAllLocation(){
String sql= "SELECT * FROM locations";
return jdbc.query(sql, locationMapper);
}
@Override // intended implementation at current: user data from templates/Landmarks/LandmarkFormTh.html is added to the Location table
public void addLocation(Location loc) {
String sql = "insert into locations( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) values (?,?,?,?,?)";
jdbc.update(sql,loc.getLocationName(),loc.getLocationEmail(),loc.getLocationDescription(),loc.getLocationPlace(),loc.getLocationTrailID());
}
}
//Holds variable data for the trails table
package Team5.SmartTowns.Data;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class trail {
private int trailsId;
private String name;
}
//Holds trails data repository
package Team5.SmartTowns.Data;
import java.util.List;
public interface trailsRepository {
List<trail> getAllTrails();
}
package Team5.SmartTowns.Data;
package Team5.SmartTowns.data;
import Team5.SmartTowns.users.User;
import Team5.SmartTowns.users.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*;
@Controller
public class DatabaseController {
@Autowired
private locationRepository locationRepository;
private LocationRepository locationRepository;
@Autowired
private trailsRepository trailsRepository;
private TrailsRepository trailsRepository;
@GetMapping("/trailList")
public ModelAndView trailList() {
ModelAndView mav1 = new ModelAndView("towns/trailsData");
List<trail> trail = trailsRepository.getAllTrails();
List<Trail> trail = trailsRepository.getAllTrails();
mav1.addObject("trails", trail);
return mav1;
}
......@@ -32,4 +32,17 @@ public class DatabaseController {
mav2.addObject("location", Locations);
return mav2;
}
//
// public List<Location> approvedLocations(){
// List<Location> locations = locationRepository.getAllLocation();
// List<Location> locationApprovalList;
//// for (int i=0;i<locations.size();i++){
//// location
// for (Location loc :locations){
// if (loc.isLocationApproved()) {
// locationApprovalList.add(loc);
// }
// } return locationApprovalList;
// }
}
//Holds variable data for the locations table (landmarks)
package Team5.SmartTowns.Data;
package Team5.SmartTowns.data;
import lombok.AllArgsConstructor;
import lombok.Data;
......@@ -11,7 +11,13 @@ public class Location {
private String locationEmail;
private String locationDescription;
private String locationPlace;
private int locationTrailID;
private String locationTrailID;
private boolean locationApproved;
public Location() {
}
@Override
public String toString() {
......@@ -21,6 +27,7 @@ public class Location {
locationDescription + '\'' +
locationPlace + '\'' +
locationTrailID +
locationApproved+
'}';
}
......@@ -40,9 +47,36 @@ public class Location {
return locationPlace;
}
public int getLocationTrailID() {
public String getLocationTrailID() {
return locationTrailID;
}
public boolean isLocationApproved() {
return locationApproved;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
public void setLocationEmail(String locationEmail) {
this.locationEmail = locationEmail;
}
public void setLocationDescription(String locationDescription) {
this.locationDescription = locationDescription;
}
public void setLocationPlace(String locationPlace) {
this.locationPlace = locationPlace;
}
public void setLocationTrailID(String locationTrailID) {
this.locationTrailID = locationTrailID;
}
public void setLocationApproved(boolean locationApproved) {
this.locationApproved = locationApproved;
}
}
//Holds locations data repository (landmarks)
package Team5.SmartTowns.Data;
package Team5.SmartTowns.data;
import java.util.List;
public interface locationRepository {
public interface LocationRepository {
List<Location> getAllLocation();
void addLocation(Location loc);
List<Location> getAllApprovedLocations();
// List<Location> getApprovedLocations2(List<Location> list);
List<Location> getAllUnapprovedLocations();
// List<Location> approvedLocations();
}
//Implements the locations repository using JDBC
package Team5.SmartTowns.data;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class LocationRepositoryJDBC implements LocationRepository {
private JdbcTemplate jdbc;
private RowMapper<Location> locationMapper;
public LocationRepositoryJDBC(JdbcTemplate aJdbc) {
this.jdbc = aJdbc;
setlocationMapper();
}
// public LocationRepositoryJDBC() {
// JdbcTemplate ajdbc = new JdbcTemplate();
// this.jdbc =ajdbc;
// setlocationMapper();
//
// }
private void setlocationMapper(){
locationMapper = (rs, i) -> new Location(
rs.getString("locationName"),
rs.getString("locationEmail"),
rs.getString("locationDescription"),
rs.getString("locationPlace"),
rs.getString("locationTrailID"),
rs.getBoolean("locationApproved")
);
}
public List<Location> getAllLocation(){
String sql= "SELECT * FROM locations";
return jdbc.query(sql, locationMapper);
}
// public LocationRepositoryJDBC() {
// JdbcTemplate ajdbc = new JdbcTemplate();
// this.jdbc =ajdbc;
// setlocationMapper();
//
// }
// public LocationRepositoryJDBC(JdbcTemplate jdbc, RowMapper<Location> locationMapper) {
// this.jdbc = jdbc;
// this.locationMapper = locationMapper;
// }
@Override
public List<Location> getAllApprovedLocations(){
String sql= "SELECT * FROM locations";
List<Location> lis = jdbc.query(sql, locationMapper);
List<Location> lisFiltered = new ArrayList<>();
for (Location li : lis){
if (li.isLocationApproved()){
lisFiltered.add(li);
}
}
return lisFiltered;
}
@Override
public List<Location> getAllUnapprovedLocations(){
String sql= "SELECT * FROM locations";
List<Location> lis = jdbc.query(sql, locationMapper);
List<Location> lisFiltered = new ArrayList<>();
for (Location li : lis){
if (!li.isLocationApproved()){
lisFiltered.add(li);
}
}
return lisFiltered;
}
@Override // intended implementation at current: user data from templates/Landmarks/LandmarkFormTh.html is added to the Location table
public void addLocation(Location loc) {
String sql = "insert into locations( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values (?,?,?,?,?,?)";
jdbc.update(sql,loc.getLocationName(),loc.getLocationEmail(),loc.getLocationDescription(),loc.getLocationPlace(),loc.getLocationTrailID(), false);
}
// @Override
// public List<Location> getApprovedLocations(){
// JdbcTemplate jdbc = new JdbcTemplate();
// List<Location> locations = new LocationRepositoryJDBC(jdbc).getAllLocation();
// List<Location> locationApprovalList= new ArrayList<Location>();
// for (Location loc :locations){
// if (loc.isLocationApproved()) {
// locationApprovalList.add(loc);
// }
// } return locationApprovalList;
// }
//
// @Override
// public List<Location> getApprovedLocations2(List<Location> list){
//
// List<Location> locationApprovalList= new ArrayList<Location>();
// for (Location loc :list){
// if (loc.isLocationApproved()) {
// locationApprovalList.add(loc);
// }
// } return locationApprovalList;
// }
//
// @Override
// public List<Location> getUnapprovedLocations(){
// List<Location> locations = getAllLocation();
// List<Location> locationUnapprovedList= new ArrayList<Location>();
// for (Location loc :locations){
// if (!loc.isLocationApproved()) {
// locationUnapprovedList.add(loc);
// }
// } return locationUnapprovedList;
// }
// public JdbcTemplate getJdbc() {
// return jdbc;
// }
}
//package Team5.SmartTowns.Data;
//
//import org.springframework.beans.factory.annotation.Autowired;
//
//import java.util.List;
//
//public class Main {
// @Autowired
// private locationRepository locationRepository;
// List<Location> approvedNumber= locationRepository.approvedLocations();
// public static void main(String[] args) {
// for (Location loc: approvedNumber){}
//
//
// }
//}
package Team5.SmartTowns.data;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.util.List;
public class MockUser {
private JdbcTemplate jdbc;
private RowMapper<Trail> trailMapper;
public List<Trail> getAllTrails(){
String sql= "SELECT * FROM trails";
return jdbc.query(sql, trailMapper);
}
}
package Team5.SmartTowns.data;
public class QRCodes {
}
//Holds variable data for the trails table
package Team5.SmartTowns.data;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Trail {
private String trailsId;
private String trailName;
private String trailNumber;
public String getTrailsId() {
return trailsId;
}
public String getTrailName() {
return trailName;
}
public String getTrailNumber() {
return trailNumber;
}
}
//Holds trails data repository
package Team5.SmartTowns.data;
import java.util.List;
public interface TrailsRepository {
List<Trail> getAllTrails();
String getTrailNameWithID(String trailsID);
}
//Implements the trails repository using JDBC
package Team5.SmartTowns.Data;
package Team5.SmartTowns.data;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
......@@ -8,21 +8,32 @@ import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class trailsRepositoryJDBC implements trailsRepository{
public class TrailsRepositoryJDBC implements TrailsRepository {
private JdbcTemplate jdbc;
private RowMapper<trail> trailMapper;
public trailsRepositoryJDBC(JdbcTemplate aJdbc){
private RowMapper<Trail> trailMapper;
public TrailsRepositoryJDBC(JdbcTemplate aJdbc){
this.jdbc = aJdbc;
settrailsMapper();
}
private void settrailsMapper(){
trailMapper = (rs, i) -> new trail(
rs.getInt("trailID"),
rs.getString("name")
trailMapper = (rs, i) -> new Trail(
rs.getString("trailID"),
rs.getString("trailName"),
rs.getString("trailNumber")
);
}
public List<trail> getAllTrails(){
public List<Trail> getAllTrails(){
String sql= "SELECT * FROM trails";
return jdbc.query(sql, trailMapper);
}
@Override
public String getTrailNameWithID(String trailsID){
String resultName = jdbc.queryForObject(
"SELECT trailName FROM trails WHERE trailID=?", String.class, trailsID);
return resultName;
}
}
package Team5.SmartTowns.Landmarks;
package Team5.SmartTowns.landmarks;
import Team5.SmartTowns.trails.Trail;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
......@@ -18,11 +16,11 @@ public class Landmarks {
// Initialized object to getID from trail.
//Predefined Landmark for Dragons Tale.
private static List<Landmarks> landmarksDragonstrail = List.of(
public static List<Landmarks> landmarksDragonstrail = List.of(
new Landmarks( 1, "A scent of...Dragon", "The Dragon has been spotted near by, find the QR code to continue" , "Start your discovery, at the sweet shop."),
new Landmarks( 2, "They've been found!", "Don't let them escape, find the next QR code to continue!", "Location test")
);
private Integer trailID;
private String trailID;
private int landmarkID;
@NotEmpty(message = "You must type in a username.")
private String landmarkName;
......@@ -43,6 +41,4 @@ public class Landmarks {
this.landmarkName = landmarkName;
this.landmarkDescription = landmarkDescription;
this.landmarkLocation = landmarkLocation; }
}
package Team5.SmartTowns.Landmarks;
package Team5.SmartTowns.landmarks;
import Team5.SmartTowns.Data.Location;
import Team5.SmartTowns.Data.locationRepository;
import Team5.SmartTowns.data.Location;
import Team5.SmartTowns.data.LocationRepository;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
......@@ -26,7 +26,7 @@ public class LandmarksController {
}
@Autowired
private locationRepository locationRepository;
private LocationRepository locationRepository;
@PostMapping("/landmarkSub")
public ModelAndView landmarkSent(@Valid @ModelAttribute("landmarkData") Landmarks landmarks, BindingResult bindingResult, Model model ) {
......@@ -37,8 +37,7 @@ public class LandmarksController {
} else{
// converts valid response using Location constructor into a submittable format to the sql table
Location loc= new Location(landmarks.getLandmarkName(), landmarks.getLandmarkEmail(), landmarks.getLandmarkDescription(), landmarks.getLandmarkLocation(), landmarks.getTrailID());
System.out.println(loc);
Location loc= new Location(landmarks.getLandmarkName(), landmarks.getLandmarkEmail(), landmarks.getLandmarkDescription(), landmarks.getLandmarkLocation(), landmarks.getTrailID(), false);
locationRepository.addLocation(loc); // adds valid landmark to locations table
ModelAndView modelAndView = new ModelAndView("redirect:/home");
return modelAndView;
......
package Team5.SmartTowns.placeswithcoordinates;
import Team5.SmartTowns.data.Location;
import Team5.SmartTowns.data.LocationRepositoryJDBC;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import java.text.DecimalFormat;
import java.util.List;
//@Data
@AllArgsConstructor
@NoArgsConstructor
public class LocationsCoordinates {
/// separate class to location to cover all locations within trails that have been approved and have long/lat coords attached for mapping.
private int locationID;
private Double locationCoordsLat;
private Double locationCoordsLong;
private JdbcTemplate jdbc;
// public List<Location> getFullApprovedLocations(JdbcTemplate aJdbc){
// JdbcTemplate jdbcSuper= new LocationRepositoryJDBC().getJdbc();
// return new LocationRepositoryJDBC(jdbcSuper).getApprovedLocations();
// }
public int getLocationID() {
return locationID;
}
public Double getLocationCoordsLong() {
return locationCoordsLong;
}
public Double getLocationCoordsLat() {
return locationCoordsLat;
}
public void setLocationCoordsLong(Double locationCoordsLong) {
this.locationCoordsLong = locationCoordsLong;
}
public void setLocationCoordsLat(Double locationCoordsLat) {
this.locationCoordsLat = locationCoordsLat;
}
// public LocationsCoordinates(JdbcTemplate aJdbc, int locationID, Double locationCoordsLat, Double locationCoordsLong) {
// super(aJdbc);
// this.locationID = locationID;
// this.locationCoordsLong = locationCoordsLong;
// this.locationCoordsLat = locationCoordsLat;
// }
// public LocationsCoordinates(int locationID, Double locationCoordsLat, Double locationCoordsLong,JdbcTemplate jdbc) {
// super(jdbc);
// this.locationID = locationID;
// this.locationCoordsLong = locationCoordsLong;
// this.locationCoordsLat = locationCoordsLat;
// }
// public LocationsCoordinates(JdbcTemplate aJdbc, int locationID, Double locationCoordsLat, Double locationCoordsLong, JdbcTemplate jdbc) {
// super(aJdbc);
// this.locationID = locationID;
// this.locationCoordsLat = locationCoordsLat;
// this.locationCoordsLong = locationCoordsLong;
// this.jdbc = jdbc;
// }
public LocationsCoordinates(int locationID, Double locationCoordsLat, Double locationCoordsLong) {
this.locationID = locationID;
this.locationCoordsLat = locationCoordsLat;
this.locationCoordsLong = locationCoordsLong;
}
// public LocationsCoordinates(JdbcTemplate aJdbc) {
// super(aJdbc);
// }
public List<Location> getFullListLocations(JdbcTemplate aJdbc){
// LocationsCoordinates jdbcSuper= new LocationsCoordinates(aJdbc);
return new LocationRepositoryJDBC(aJdbc).getAllLocation();
}
// public List<Location> getFullApprovedLocations(JdbcTemplate aJdbc){
// JdbcTemplate jdbcSuper= new LocationRepositoryJDBC().getJdbc();
// return new LocationRepositoryJDBC(jdbcSuper).getApprovedLocations();
// }
//
// public List<Location> getFullUnapprovedLocations(JdbcTemplate aJdbc){
//// LocationsCoordinates jdbcSuper= new LocationsCoordinates(aJdbc);
// return new LocationRepositoryJDBC(aJdbc).getUnapprovedLocations();
// }
/// Need a constructor to create a locations list, approved collation list, unapproved locations list.
}
package Team5.SmartTowns.placeswithcoordinates;
import Team5.SmartTowns.data.Location;
import Team5.SmartTowns.data.LocationRepository;
import Team5.SmartTowns.data.Trail;
import Team5.SmartTowns.data.TrailsRepository;
import jakarta.validation.constraints.Max;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
@Controller
public class PlacesController {
@Autowired
private PlacesCoordinatesRepository placeRepo;
@Autowired
private LocationRepository locationRepo;
@Autowired
private TrailsRepository trailsRepo;
@GetMapping("/checkpoints")
public ModelAndView getLocationPages(){
ModelAndView modelAndView = new ModelAndView("landmarks/locationPage.html");
List<LocationsCoordinates> locCoords = placeRepo.getAllLocationCoords();
List<Location> approvedLocations = locationRepo.getAllApprovedLocations();
modelAndView.addObject("location", approvedLocations);
modelAndView.addObject("locationCoords", locCoords);
return modelAndView;
}
@RequestMapping(value="/location", method= RequestMethod.POST)
public String sendHtmlFragmentLocation(Model map) {
map.addAttribute("foo", "bar");
return "checkpoint/checkpoint";
}
@GetMapping("/checkpoints/{location}")
public ModelAndView getResultBySearchKeyLocation(@PathVariable String location) {
List<LocationsCoordinates> locCoords = placeRepo.getAllLocationCoords();
List<Location> approvedLocations = locationRepo.getAllApprovedLocations();
int locationID = 999;
for (int i=0;i<approvedLocations.size();i++){
if ( (approvedLocations.get(i).getLocationName().replace(' ', '-').trim().equals(location)) ){
locationID= i;
}
}
String trailName=trailsRepo.getTrailNameWithID(approvedLocations.get(locationID).getLocationTrailID()).replace(' ', '-').trim();
ModelAndView modelAndView= new ModelAndView("fragments/locationPageFrags :: locationSection");
modelAndView.addObject("locCoord", locCoords.get(locationID));
modelAndView.addObject("trail", trailName);
modelAndView.addObject("location", approvedLocations.get(locationID));
return modelAndView;
}
/// Trail webpage mapping
@GetMapping("/trails")
public ModelAndView getTrailsPage(){
ModelAndView modelAndView = new ModelAndView("landmarks/trailsPage.html");
List<LocationsCoordinates> locCoords = placeRepo.getAllLocationCoords();
List<Location> approvedLocations = locationRepo.getAllApprovedLocations();
List<Trail> trailslocations = trailsRepo.getAllTrails();
List<Location> locationCoordsWorkaround = new ArrayList<Location>();
modelAndView.addObject("trails", trailslocations);
modelAndView.addObject("locations", approvedLocations);
modelAndView.addObject("locationCoords", locCoords);
return modelAndView;
}
@RequestMapping(value="/trail", method= RequestMethod.POST)
public String sendHtmlFragmentTrail(Model map) {
map.addAttribute("foo", "bar");
return "trail/trail";
}
@GetMapping("/trails/{trail}")
public ModelAndView getResultBySearchKeyTrails(@PathVariable String trail) {
List<LocationsCoordinates> locCoords = placeRepo.getAllLocationCoords();
List<Location> approvedLocations = locationRepo.getAllApprovedLocations();
List<Trail> trailslocations = trailsRepo.getAllTrails();
int trailID = 999;// otherwise cases errors e.g. null used. 999 unlikely to be used so safe until then
for (int i=0;i<trailslocations.size();i++){
if (trailslocations.get(i).getTrailName().replace(' ', '-').trim().equals(trail)){
trailID=i;
break;}
}
ModelAndView modelAndView= new ModelAndView("fragments/trailsPageFrags :: trailsSection");
modelAndView.addObject("trail", trailslocations.get(trailID));
modelAndView.addObject("locCoords", locCoords);
modelAndView.addObject("locations", approvedLocations);
return modelAndView;
}
}
package Team5.SmartTowns.placeswithcoordinates;
import Team5.SmartTowns.data.Location;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public interface PlacesCoordinatesRepository {
List<LocationsCoordinates> getAllLocationCoords();
void addLocationCoord(LocationsCoordinates locCoord);
List<TownWithTrails> getAllTownCoords();
void addTownWithCoords(TownWithTrails town);
// List<Location> getFullApprovedLocations(JdbcTemplate aJdbc);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment