From a06df64deebe24dffe0278ba71b6f86b86d15f3b Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@nibio.no>
Date: Wed, 24 May 2017 11:05:31 -0700
Subject: [PATCH] Made sure all poi names are unique
---
.../servlet/PointOfInterestController.java | 14 +++++++++++++-
.../session/PointOfInterestBean.java | 14 ++++++++++++++
.../vips/logic/entity/PointOfInterest.java | 1 +
.../vips/logic/service/LogicService.java | 9 +++++++++
.../vips/logic/i18n/vipslogictexts.properties | 1 +
.../logic/i18n/vipslogictexts_bs.properties | 1 +
.../logic/i18n/vipslogictexts_hr.properties | 1 +
.../logic/i18n/vipslogictexts_nb.properties | 1 +
.../logic/i18n/vipslogictexts_sr.properties | 1 +
.../i18n/vipslogictexts_zh_CN.properties | 1 +
src/main/webapp/templates/poiForm.ftl | 19 ++++++++++++++++++-
11 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java
index 460e8faf..e0c9a16c 100755
--- a/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java
+++ b/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java
@@ -47,6 +47,7 @@ import no.nibio.vips.logic.util.SessionControllerGetter;
import no.nibio.vips.util.ExceptionUtil;
import no.nibio.vips.util.ServletUtil;
import no.nibio.vips.logic.entity.WeatherForecastProvider;
+import no.nibio.vips.logic.i18n.SessionLocaleUtil;
import no.nibio.vips.logic.util.GISUtil;
import no.nibio.vips.logic.util.Globals;
import no.nibio.web.forms.FormField;
@@ -593,7 +594,8 @@ public class PointOfInterestController extends HttpServlet {
)
{
FormValidation formValidation = FormValidator.validateForm("poiForm", request, getServletContext());
- if(formValidation.isValid())
+ Boolean poiNameAlreadyExists = SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(formValidation.getFormField("name").getWebValue()) != null;
+ if(formValidation.isValid() && ! poiNameAlreadyExists)
{
// Set values
poi.setName(formValidation.getFormField("name").getWebValue());
@@ -694,15 +696,25 @@ public class PointOfInterestController extends HttpServlet {
}
else
{
+ if(poiNameAlreadyExists)
+ {
+ FormField poiNameField = formValidation.getFormField("name");
+ poiNameField.setValid(false);
+ poiNameField.setValidationMessage(SessionLocaleUtil.getI18nBundle(request).getString("nameAlreadyExists"));
+ }
request.setAttribute("formValidation", formValidation);
request.setAttribute("poi", poi);
request.setAttribute("defaultMapCenter",user.getOrganizationId().getDefaultMapCenter());
request.setAttribute("defaultMapZoom", user.getOrganizationId().getDefaultMapZoom());
+ request.setAttribute("returnURL","poi?organizationId=" + user.getOrganizationId().getOrganizationId());
+ // Finding all external resources where entry is missing
+ request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getPointOfInterestBean().getUnusedExternalResourcesForPointOfInterest(poi));
request.getSession().setAttribute("availableTimeZones", Globals.availableTimeZones);
request.getSession().setAttribute("defaultTimeZoneId", user.getOrganizationId().getDefaultTimeZone());
request.getSession().setAttribute("availableCountries", em.createNamedQuery("Country.findAll").getResultList());
request.getSession().setAttribute("defaultCountryCode", user.getOrganizationId().getCountryCode().getCountryCode());
request.getRequestDispatcher("/poiForm.ftl").forward(request, response);
+
}
}
else
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
index c8db2dfe..51e459f7 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
@@ -441,5 +441,19 @@ public class PointOfInterestBean {
.getResultList();
}
+ public PointOfInterest getPointOfInterest(String poiName) {
+ try
+ {
+ return em.createNamedQuery("PointOfInterest.findByNameCaseInsensitive", PointOfInterest.class)
+ .setParameter("name", poiName)
+ .getSingleResult();
+ }
+ catch(NoResultException ex)
+ {
+ return null;
+ }
+
+ }
+
}
diff --git a/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java b/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java
index 81088def..1ad8f99e 100755
--- a/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java
+++ b/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java
@@ -66,6 +66,7 @@ import no.nibio.vips.logic.util.GISUtil;
@NamedQuery(name = "PointOfInterest.findByOrganizationId", query = "SELECT p FROM PointOfInterest p WHERE p.userId IN(SELECT u.userId FROM VipsLogicUser u WHERE u.organizationId=:organizationId OR u.organizationId IN (SELECT o.organizationId FROM Organization o WHERE o.parentOrganizationId = :organizationId)) ORDER BY p.name ASC"),
@NamedQuery(name = "PointOfInterest.findForecastLocationsByOrganizationId", query = "SELECT p FROM PointOfInterest p WHERE p.isForecastLocation IS TRUE AND p.userId IN(SELECT u.userId FROM VipsLogicUser u WHERE u.organizationId=:organizationId OR u.organizationId IN (SELECT o.organizationId FROM Organization o WHERE o.parentOrganizationId = :organizationId)) ORDER BY p.name ASC"),
@NamedQuery(name = "PointOfInterest.findByName", query = "SELECT p FROM PointOfInterest p WHERE p.name = :name"),
+ @NamedQuery(name = "PointOfInterest.findByNameCaseInsensitive", query = "SELECT p FROM PointOfInterest p WHERE lower(p.name) = lower(:name)"),
//@NamedQuery(name = "PointOfInterest.findByLongitude", query = "SELECT p FROM PointOfInterest p WHERE p.longitude = :longitude"),
//@NamedQuery(name = "PointOfInterest.findByLatitude", query = "SELECT p FROM PointOfInterest p WHERE p.latitude = :latitude"),
//@NamedQuery(name = "PointOfInterest.findByAltitude", query = "SELECT p FROM PointOfInterest p WHERE p.altitude = :altitude"),
diff --git a/src/main/java/no/nibio/vips/logic/service/LogicService.java b/src/main/java/no/nibio/vips/logic/service/LogicService.java
index fd408e04..c68cfc90 100755
--- a/src/main/java/no/nibio/vips/logic/service/LogicService.java
+++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java
@@ -369,6 +369,15 @@ public class LogicService {
return Response.ok().entity(retVal).build();
}
+ @GET
+ @Path("poi/name/{poiName}")
+ @Produces("application/json;charset=UTF-8")
+ public Response getPoiByName(@PathParam("poiName") String poiName)
+ {
+ PointOfInterest retVal = SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(poiName);
+ return retVal != null ? Response.ok().entity(retVal).build() : Response.noContent().build();
+ }
+
@GET
@Path("poi/user/")
@Produces("application/json;charset=UTF-8")
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
index 1868bb39..373038dc 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
@@ -441,3 +441,4 @@ isRequiredField=Required field
crops=Crops
unknownOrganismId=Unknown Organism Id
vipsLogicRole_7=Organism editor
+nameAlreadyExists=The name already exists
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
index dc6f450a..b5beee4a 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
@@ -441,3 +441,4 @@ isRequiredField=Required field
crops=Crops
unknownOrganismId=Unknown Organism Id
vipsLogicRole_7=Organism editor
+nameAlreadyExists=The name already exists
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
index 0b9d1157..dfc93238 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
@@ -440,3 +440,4 @@ isRequiredField=Required field
crops=Crops
unknownOrganismId=Unknown Organism Id
vipsLogicRole_7=Organism editor
+nameAlreadyExists=The name already exists
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
index 216d3ba0..3cea3335 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
@@ -441,3 +441,4 @@ isRequiredField=Obligatorisk felt
crops=Kulturer
unknownOrganismId=Ukjent organismeId
vipsLogicRole_7=Organismeredakt\u00f8r
+nameAlreadyExists=Navnet er allerede i bruk
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
index 8e3b9971..cca159c3 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
@@ -441,3 +441,4 @@ isRequiredField=Required field
crops=Crops
unknownOrganismId=Unknown Organism Id
vipsLogicRole_7=Organism editor
+nameAlreadyExists=The name already exists
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
index 6c324faa..4dfd6a77 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
@@ -438,3 +438,4 @@ isRequiredField=Required field
crops=Crops
unknownOrganismId=Unknown Organism Id
vipsLogicRole_7=Organism editor
+nameAlreadyExists=The name already exists
diff --git a/src/main/webapp/templates/poiForm.ftl b/src/main/webapp/templates/poiForm.ftl
index a72bfaa1..80bc9bd0 100755
--- a/src/main/webapp/templates/poiForm.ftl
+++ b/src/main/webapp/templates/poiForm.ftl
@@ -41,6 +41,23 @@
initMap([${defaultMapCenter.x?c},${defaultMapCenter.y?c}],${defaultMapZoom},${user.organizationId.organizationId},${poi.pointOfInterestId!"null"});
</#if>
});
+
+ // POI name must be unique
+ function checkPoiNameAvailability(poiNameField)
+ {
+ var poiName = poiNameField.value;
+ if(poiName.length > 0)
+ {
+ $.getJSON( "/rest/poi/name/" + poiName)
+ .done(function(json, status, jx){
+ if(jx.status==200)
+ {
+ var theForm = document.getElementById("poiForm");
+ invalidizeField(poiNameField, theForm, "${i18nBundle.nameAlreadyExists}",null);
+ }
+ });
+ }
+ }
</script>
</#macro>
<#macro page_contents>
@@ -61,7 +78,7 @@
<input type="hidden" name="pointOfInterestId" value="${poi.pointOfInterestId!"-1"}"/>
<div class="form-group">
<label for="name">${i18nBundle.name}</label>
- <input type="text" class="form-control" name="name" placeholder="${i18nBundle.name}" value="${(poi.name)!""}" onblur="validateField(this);"/>
+ <input type="text" class="form-control" name="name" placeholder="${i18nBundle.name}" value="${(poi.name)!""}" onblur="validateField(this); checkPoiNameAvailability(this);"/>
<span class="help-block" id="${formId}_name_validation"></span>
</div>
<div class="form-group">
--
GitLab